What's pros and cons of using Enterprise Library Unity vs other IoC containers (Windsor, Spring.Net, Autofac ..)?
I am preparing a presentation for a usergroup. As such I just went through a bunch of them. Namely: AutoFac, MEF, Ninject, Spring.Net, StructureMap, Unity, and Windsor.
I wanted to show off the 90% case (constructor injection, which is mainly what people use an IOC for anyway). You can check out the solution here (VS2008)
As such, there are a few key differences:
Each of them have other features as well (some have AOP, and better gizmos, but generally all I want an IOC to do is create and retrieve objects for me)
Note: the differences between the different libraries object retrieval can be negated by using the CommonServiceLocator: http://www.codeplex.com/CommonServiceLocator
That leaves us with initialization, which is done in two ways: via code or via XML configuration (app.config/web.config/custom.config). Some support both, some support only one. I should note: some use attributes to help the IoC along.
So here is my assessment of the differences:
Code initialization only (with attributes). I hope you like lambdas. Initialization code looks like this:
IKernel kernel = new StandardKernel(
new InlineModule(
x => x.Bind<ICustomerRepository>().To<CustomerRepository>(),
x => x.Bind<ICustomerService>().To<CustomerService>(),
x => x.Bind<Form1>().ToSelf()
));
Initialization code or XML or Attributes. v2.5 is also very lambda'y. All in all, this is one of my favorites. Some very interesting ideas around how StructureMap uses Attributes.
ObjectFactory.Initialize(x =>
{
x.UseDefaultStructureMapConfigFile = false;
x.ForRequestedType<ICustomerRepository>()
.TheDefaultIsConcreteType<CustomerRepository>()
.CacheBy(InstanceScope.Singleton);
x.ForRequestedType<ICustomerService>()
.TheDefaultIsConcreteType<CustomerService>()
.CacheBy(InstanceScope.Singleton);
x.ForConcreteType<Form1>();
});
Initialization code and XML. Nice library, but XML configuration is a pain in the butt. Great library for Microsoft or the highway shops. Code initialization is easy:
container.RegisterType<ICustomerRepository, CustomerRepository>()
.RegisterType<ICustomerService, CustomerService>();
XML only as near as I can tell. But for functionality Spring.Net does everything under the sun that an IoC can do. But because the only way to unitize is through XML it is generally avoided by .net shops. Although, many .net/Java shop use Spring.Net because of the similarity between the .net version of Spring.Net and the Java Spring project.
Note: Configuration in the code is now possible with the introduction of Spring.NET CodeConfig.
XML and code. Like Spring.Net, Windsor will do anything you could want it to do. Windsor is probably one of the most popular IoC containers around.
IWindsorContainer container = new WindsorContainer();
container.AddComponentWithLifestyle<ICustomerRepository, CustomerRepository>("CustomerRepository", LifestyleType.Singleton);
container.AddComponentWithLifestyle<ICustomerService, CustomerService>("CustomerService",LifestyleType.Singleton);
container.AddComponent<Form1>("Form1");
Can mix both XML and code (with v1.2). Nice simple IoC library. Seems to do the basics with not much fuss. Supports nested containers with local scoping of components and a well-defined life-time management.
Here is how you initialize it:
var builder = new ContainerBuilder();
builder.Register<CustomerRepository>()
.As<ICustomerRepository>()
.ContainerScoped();
builder.Register<CustomerService>()
.As<ICustomerService>()
.ContainerScoped();
builder.Register<Form1>();
If I had to choose today: I would probably go with StructureMap. It has the best support for C# 3.0 language features, and the most flexibility in initialization.
Note: Chris Brandsma turned his original answer into a blog post.