Blog Archives

How We Do Dependency Injection

Dependency Injection (DI) design pattern has become more and more popular in software development recent years. There are many open source frameworks that help us apply DI design pattern out there, like Castle Windsor, NInject, StructureMap, Unity,… just named a few. From my point of view, using a framework for DI means using an Inversion of Control (IoC) container to wire up the dependencies between objects and let it manages their life cycles after registering the object graphs with that container.


Almost softwares I built in recent 2-3 years have been applied DI design pattern with a help of an IoC container. For what? you may ask. Well, I think the benefit of applying DI is that it allows me to design loosely coupled objects to ease unit testing. At run time, the IoC container helps wire up all the dependencies between objects for me.

However, using an IoC container for DI in building softwares doesn’t mean I always use it in a right way. In other words, there was a bad practice applied when using an IoC container. One of the wrong way I can tell you is making an IoC container static or singleton and use it in many places, across layers which is supposed to be a Service Locator (anti-)pattern. If you want to be clear, read this: http://www.devtrends.co.uk/blog/how-not-to-do-dependency-injection-the-static-or-singleton-container, or even if you want to be more serious on the topic, read this article and the comments too: http://blog.ploeh.dk/2010/02/03/ServiceLocatorIsAnAntiPattern.aspx

After reading those two articles and agreed with the authors, I realized that I have used the static IoC container in many softwares I built. So I decided to re-factored our code to avoid doing that wrong thing again. The IoC container that I am familiar with is Castle Windsor. I used it from the time I knew what DI is, and I am still using it just because I like the way to register types with IWindsorContainer using fluent interfaces that is very readable.

To demonstrate, here is an ASP.NET MVC application that used the Service Locator to resolve the services on which a controller depends.

The static IoC container class:

public static class IoC
{
    public static IWindsorContainer Container { get; set; }
}

The IoC.Container static property will be assigned to an instance of WindsorContainer class in the global MvcApplication (Global.ascx.cs) and it as well will be used to register types at web application start up:

public class MvcApplication : System.Web.HttpApplication
{
    static MvcApplication()
    {
        IoC.Container = new WindsorContainer();
        RegisterComponentsWith(IoC.Container);
    }

    private static void RegisterComponentsWith(IWindsorContainer container)
    {
        container.Register(Component.For<IRepository>().ImplementedBy<Repository>().LifeStyle.Transient);
        container.Register(Component.For<IAccountService>().ImplementedBy<AccountService>().LifeStyle.Transient);
        container.Register(Component.For<IEmailService>().ImplementedBy<EmailService>().LifeStyle.Transient);
container.Register(Component.For<IFormsAuthenticationService>().ImplementedBy<FormsAuthenticationService>().LifeStyle.Transient);
        // other type registrations...
    }
}

And this is how we use that IoC container to resolve service types in a controller:

public class AccountController : Controller
{
    public T GetService<T>()
    {
        return IoC.Container.Resolve<T>();
    }

    public AccountController()
    {
    }
    public ActionResult LogOn(LogOnModel model)
    {
        if (ModelState.IsValid)
        {
            IAccountService accountService = GetService<IAccountService>();
            if (accountService.ValidateLogin(model.Email, model.Password))
            {
                // code...
            }
            // rest of the code...
        }
        // rest of the code...
    }
    // rest of the code
}

Now I am using an IoC container badly and _without_ dependency injection. So how to apply DI correctly, you ask? The solution is to get rid of static IoC container and remove the dependency to that container from not only the controller(s) but also anywhere on the code, except the code that instantiates the container and registers the object graphs in the global MvcApplication.

Here is the refactored AccountController that applies DI correctly

public class AccountController : Controller
{
    private readonly IAccountService _accountService;
    private readonly IEmailService _emailService;
    private readonly IFormsAuthenticationService _formsAuthenticationService;

    public AccountController(IAccountService accountService,
        IEmailService emailService,
        IFormsAuthenticationService formsAuthenticationService)
    {
        _accountService = accountService;
        _emailService = emailService;
        _formsAuthenticationService = _formsAuthenticationService;
    }
    public ActionResult LogOn(LogOnModel model)
    {
        if (ModelState.IsValid)
        {
            if (_accountService.ValidateLogin(model.Email, model.Password))
            {
                // code...
            }
            // rest of the code...
        }
        // rest of the code...
    }
    // rest of the code
}

We also need to implement a custom controller factory that is responsible for creating an appropriate controller and also injecting the services on which that controller depends. Here is the custom controller factory which inherits from ASP.NET MVC’s DefaultControllerFactory class:

public class WindsorControllerFactory : DefaultControllerFactory
{
    private readonly IWindsorContainer _container;

    public WindsorControllerFactory(IWindsorContainer container)
    {
        _container = container;
    }

    protected override IController GetControllerInstance(System.Web.Routing.RequestContext requestContext, Type controllerType)
    {
        if (controllerType == null)
            throw new HttpException(404, string.Format("The controller for path '{0}' could not be found or it does not implement IController.",
                requestContext.HttpContext.Request.Path));

        return (IController)_container.Resolve(controllerType);
    }

    public override void ReleaseController(IController controller)
    {
        _container.Release(controller);
    }
}}

Here is the revised code to instantiate the container and register types with it in MvcApplication class:

public class MvcApplication : System.Web.HttpApplication
{
    private static IWindsorContainer _container = new WindsorContainer();
    static MvcApplication()
    {
        RegisterComponentsWith(_container);
    }

    protected void Application_Start()
    {
        AreaRegistration.RegisterAllAreas();

        RegisterGlobalFilters(GlobalFilters.Filters);
        RegisterRoutes(RouteTable.Routes);
        ControllerBuilder.Current.SetControllerFactory(new WindsorControllerFactory(_container));
    }

    private static void RegisterComponentsWith(IWindsorContainer container)
    {
        container.Register(Component.For<IRepository>().ImplementedBy<Repository>().LifeStyle.Transient);
        container.Register(Component.For<IAccountService>().ImplementedBy<AccountService>().LifeStyle.Transient);
        container.Register(Component.For<IEmailService>().ImplementedBy<EmailService>().LifeStyle.Transient);
        container.Register(Component.For<IFormsAuthenticationService>().ImplementedBy<FormsAuthenticationService>().LifeStyle.Transient);

        // register controllers with the container
        container.Register(
                AllTypes.FromThisAssembly()
                .BasedOn<IController>()
                .Configure(c => c.LifeStyle.Transient));
        // other type registrations...
    }

    // code...
}

Now I am using DI correctly. But there still is a problem to me: since I want to use dependency injection, I have to list out all the dependencies to services in controller constructor, here I use constructor injection or I may opt to use property injection. Both ways leads me to have a ‘greedy’ controller because there are controller’s action methods being invoked  that do not actually use any of dependent services at all!

After a while looking for a way to solve the problem, I found that Castle Windsor has a feature called TypedFactoryFacility that allows us to define an interface as a factory which, once registered with the container, will resolves the types for us on behalf of container. Note that we don’t need to provide any implementation for that typed service factory interface at all.

Here is the typed factory interface to resolve the service(s):

public interface IServiceFactory
{
    T Create<T>();

    void Release(object service);
}

Register the typed factory with the container:

// code..
container.Register(Component.For<IRepository>().ImplementedBy<Repository>().LifeStyle.Transient);
container.Register(Component.For<IAccountService>().ImplementedBy<AccountService>().LifeStyle.Transient);
container.Register(Component.For<IEmailService>().ImplementedBy<EmailService>().LifeStyle.Transient);
container.Register(Component.For<IFormsAuthenticationService>().ImplementedBy<FormsAuthenticationService>().LifeStyle.Transient);
// code..
container.AddFacility<TypedFactoryFacility>();
container.Register(
    Component.For<IServiceFactory>()
        .AsFactory()
        .LifeStyle.Transient);
// code..

Use the typed factory in the controller to resolve the designed service once we really need it:

public class AccountController : ControllerBase
{
    private readonly IServiceFactory _serviceFactory;
    public AccountController(IServiceFactory serviceFactory)
    {
        _serviceFactory = serviceFactory;
    }

    [HttpPost]
    public ActionResult LogOn(LogOnModel model)
    {
        if (ModelState.IsValid)
        {
            IAccountService accountService = _serviceFactory.Create<IAccountService>();
            if (accountService.ValidateLogin(model.Email, model.Password))
            {
                IFormsAuthenticationService formsAuthenticationService = _serviceFactory.Create<IForsAuthenticationService>();
                formsAuthenticationService.SignIn(model.Email, model.RememberMe);
                _serviceFactory.Release(formsAuthenticationService);
                // rest of code...
            }
            _serviceFactory.Release(accountService);
            // rest of code...
        }
        // rest of code...
    }
    // rest of code
}

From the code, every when you call:

IAccountService accountService = _serviceFactory.Create<IAccountService>();

…is  equivalent of calling:

IAccountService accountService = kernel.Resolve<IAccountService>();

That’s it. I hope you understand how  to apply DI correctly and also find the usefulness of Castle Windsor’s TypedFactoryFacility.

Comments are welcome.

Advertisements