Friday, April 23, 2010

How to decouple your application from IoC container implementation

As we all know, DI(Dependency Injection) is a form of IoC(Inversion of Control). when I use IoC Containers like Unity or Autofac to implement dependency injection, my application will be dependent on that framework, so if i decide to go for another IoC Container, I need to change a lot of things.what I want to achieve is how to make this change easier and how to decouple my application from any specific container. what i did is creating an interface to work with.

I need to add a reference to Microsoft.Practices.ServiceLocation.dll
and I make use of IServiseLocator interface in that assembly.
using Microsoft.Practices.ServiceLocation;

public abstract class IocContainer
   public static IServiceLocator Locator;

   protected IocContainer()
      Locator = CreateServiceLocator();

  protected abstract IServiceLocator CreateServiceLocator();

public class IocContainerInitialization
  private static IocContainer _iocContainer;

  public static void Initialize(IocContainer iocContainer)
    _iocContainer = iocContainer;

  public static IocContainer IocContainer
    get { return _iocContainer; }

//then for every IoC Container I want to use, I need to create a container //inheriting from that base IoCContainer class.

//for example, for using Autofac

using Autofac.Integration.Web;
using Autofac.Integration.Web.Mvc;
using AutofacContrib.CommonServiceLocator;
using Microsoft.Practices.ServiceLocation;

public class AutofacIocContainer : IocContainer
  protected override IServiceLocator CreateServiceLocator()
    var containerBuilder = new ContainerBuilder();

    //For MVC-------------

    ContainerProvider containerProvider = new ContainerProvider(containerBuilder.Build());

    //For MVC-------------------------------
    System.Web.Mvc.ControllerBuilder.Current.SetControllerFactory(new  AutofacControllerFactory(containerProvider));

    return new AutofacServiceLocator(containerProvider.ApplicationContainer);

  private static void RegisterTypes(ContainerBuilder container)
    //Cache per request
    container.Register(c => new DbHelper("MyConnectionString")).As().InstancePerLifetimeScope();

    container.Register(c => new DbMapper(c.Resolve())).As();
    container.Register(c => new TagRepository()).As();
    container.Register(c => new UserRepository()).As();

//Then, in your Global.asax file we need to initialize our Container.

void Application_Start(object sender, EventArgs e)
  IocContainerInitialization.Initialize(new AutofacIocContainer());

Now, if you want to switch to another IoC Container, you only need to change one line and initialize another container.



Post a Comment