I read on this post that they are using dependency injection to load repository instance on each mvc request.
I'm not sure if I understand correctly but I currently using in my mvc app. UserRepository
which implements IUserRepository
interface. This interface is injected in controller constructor
public class UserController : Controller
{
private IUserRepository repository;
public UserController(IUserRepository rep)
{ repository = rep; }
public UserController() : this(new UserRepository()) {}
}
but I don't see any benefit using this interface (IUserRepository
) I could use UserRepository
without interface. Obviously someone smarter is figured that is right approach (I've found it on apress mvc4 book) and I would kindly ask someone to elaborate why is this better approach instead of using repository without interface.
Having this in mind I would ask anyone to share concrete examples or links on how to implement this approach (using dependency injection to load repository instance on each mvc request).
The main idea behind DI is to force you to see the big picture instead of concrete implementations.
Your controller needs to get the user, but it shouldn't care about concrete implementation (does your repository fetch the user from the database, web service, xml file, etc. or does it use Linq2Sql, EntityFramework, Dapper or something else under the hood).
Your controller is dependent on that piece of code which can be injected in constructor, property or method, but it doesn't really care about concrete implementation.
DI removes the tight coupling between your controller and repository, allows you to write unit tests by mocking the repository, and you can easily change the concrete implementation of your repository (eg. use PetaPoco instead of EntityFramework) without touching the rest of the code.
You should also take a look at the SOLID principles: http://en.wikipedia.org/wiki/SOLID_(object-oriented_design)
When my team started using dependency injection we were reading a good book "Pro ASP.NET MVC 2 Framework" by Steven Sanderson. In this book he describes how to work with Castle Windsor, a popular dependency injection framework. In another book "Pro ASP.NET MVC 3 Framework", as I know, how to use Ninject (another framework) is described.
In order to use Castle Windsor:
First you have to write your custom implementation of controller factory:
/// <summary>
/// Controller factory the class is to be used to eliminate hard-coded dependencies
/// between controllers and other components
/// </summary>
public class ControllerFactory : DefaultControllerFactory
{
private readonly IWindsorContainer container;
public WindsorControllerFactory(IWindsorContainer container)
{
this.container = container;
}
public override void ReleaseController(IController controller)
{
container.Release(controller.GetType());
}
protected override IController GetControllerInstance(System.Web.Routing.RequestContext requestContext, Type controllerType)
{
return (IController)container.Resolve(controllerType);
}
}
Then you have to write an installer for all your controllers.
/// <summary>
/// Castle windsor installer for controller components.
/// </summary>
public class ControllersInstaller : IWindsorInstaller
{
/// <summary>
/// Performs the installation in the <see cref="T:Castle.Windsor.IWindsorContainer"/>.
/// </summary>
/// <param name="container">The container.</param>
/// <param name="store">The configuration store.</param>
public void Install(IWindsorContainer container, IConfigurationStore store)
{
container.Register(
Classes.FromThisAssembly()
.BasedOn<IController>()
.LifestyleTransient()
);
}
}
If you want your repositories to be resolved as dependencies you should write an installer for them also. It will be similar to ControllersInstaller but lifestyle will be LifestylePerWebRequest(). PerRequestLifestyle should be registered in web.config file.
<httpModules>
<add name="PerRequestLifestyle" type="Castle.MicroKernel.Lifestyle.PerWebRequestLifestyleModule, Castle.Windsor" />
</httpModules>
And then you have to create an instance of container when application starts in Global.asax.cs:
public class MvcApplication : System.Web.HttpApplication
{
private static IWindsorContainer container;
protected void Application_Start()
{
container = new WindsorContainer();
container.Install(FromAssembly.This());
//Set the controller builder to use our custom controller factory
var controllerFactory = new WindsorControllerFactory(container);
ControllerBuilder.Current.SetControllerFactory(controllerFactory);
}
protected void Application_End()
{
container.Dispose();
}
}
There is also a link to Castle Windsor documentation where you can find more information about working with lifestyles and ASP.NET MVC 3 application tutorial.
** When you use interfaces
** You do not need default constructors in your controllers if you have controller factory implemented and set up.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With