About a year ago I wrote a comparison of .NET IoC frameworks (part 1, part 2), which turned out to be somewhat popular. I was pretty sure it is quite obsolete by now.

However, when Chris Tacke asked me to review OpenNETCF IoC framework (built for .NET CF) I have decided to update the charts on Google Code wiki.

Now I updated all frameworks there to the latest versions. I am not sure I got everything correctly this time, because I didn’t want to spend too much time on this. If I made an error in description of your framework features, just tell.

It is interesting that there are almost no significant changes in tests I have. Changes seem to slow down since the time I was writing the original posts. I think there are two reasons for that: frameworks being feature-complete enough not to need rapid evolution and me missing new features because my original test scope is somewhat obsolete. I am almost sure I will not have time to research all new developments, which is unfortunate.

As I said in a previous post, in addition to the charts, Google Code project has test adapters for all frameworks, which can be used as sample integration code. If there is something I do with your framework that can be done in a better way, tell me. I will also grant write rights on repository to any interested framework authors.

Note to RSS users: There are embedded spreadsheets in this posts that Google Reader silently hides. I prefer RSS myself, but for this post Zoho features are very useful and, unfortunately, I see no way to make it usable in Google Reader. Sorry about that.

See also: .NET DI (IoC) Frameworks, Revisited.

Update: Several people have pointed to the fact that some issues mentioned in my post are no longer relevant. I will try to mention it, but in general this post reflects only the versions I have listed in the previous one.

However, Jeremy Miller (author of StructureMap) has pointed to a significant oversight in my review: StructureMap is not limited to static APIs. Since this error is so large and relevant to the reviewed version, I am completely rewriting this part now.

I have finished the previous post with a summary of basic injection/autowiring features. It would be great to say that I will cover all remaining features in this part.

However, it is not possible to review and compare every single feature of all IoC frameworks, and some things (like AOP) I felt to be outside of the scope of IoC functionality. So this review will be somewhat limited, but, I hope, still useful.

4. Lifestyles

As you can see, all frameworks support two basic lifestyles, transient and singletons. In addition to this, all of them have an ability to define custom lifestyles (the specific APIs are named quite differently between frameworks).

I have also added support for custom instance registration to the same table (custom instances are instances built outside of the container and then provided as an implementation of some service interface). This support is also strong in all reviewed frameworks.

The interesting thing that can be learned here is that extensible lifestyles system is a baseline feature for any IoC framework, something that must be supported. This is quite understandable for singletons and transients, but it is nice to see that extensibility is also very popular.

5. Advanced resolution

While the previous section deals with the baseline features, this section contains advanced features that I feel should be a new baseline.

So, what is it all about?

Open generics injection is an ability to register open generic types and receive specific generic types on demand. Basically, it is about registering Component<> as IService<> (not giving any generic arguments), and on request of IService<X> getting Component<X>.

It seems most framework authors tend to agree that is an useful feature, so all frameworks except Spring.Net support open generics injection. I think it is already very near to a new baseline. Thanks to Castle guys for introducing it.

List injection is something I already discussed in a previous post. It is an ability to register several IService implementations, and then get them all through IService[] (IList/IEnumerable/…) dependency. I have found it very useful, and I hoping it would become a new baseline some day.

I was very surprised by StructureMap actually supporting this functionality (I haven’t found it documented anywhere, but tests clearly show it does at least for arrays). Spring.NET, in exactly reversed fashion, has it documented, but broken in the release I have tested (see link in the table, howevers, seems to be fixed in the 1.2.0).

All other frameworks do not support list injection out of the box. It is probably implementable in most of them, so it is not such a big deal. However, I have tried to build an ArraySubDependencyResolver for Castle, and while trivial implementation works, correctly supporting circular references is a major pain I haven’t solved yet.

Unregistered resolution is also something I have talked about, as a solution to container pollution (nice rhyme!). It was a nice surprise to see that most of the frameworks except Castle and, it seems, Spring.Net have this feature. In Autofac you have to allow specific types to be resolvable, however it seems to work pretty well.

6. Final overview

The last section of this comparison will be the most subjective. The first thing I want to include is auto-mocking. Auto-mocking as a problem is well described in this post. In a nutshell, it is an ability to leverage IoC framework to automatically mock dependencies of the tested component.

IoC frameworks often position themselves as tools to simplify mocking, so I think it is important to have this simplification not only on the architectural level, but on the tool level as well. Of course, different people like different mock frameworks, however having an example integration with any mock framework really helps to implement your own.

In addition to auto-mocking, I added to the final overview some interesting features that are present in a single framework, and issues I encountered while working with specific frameworks.

As we can see, Autofac and StructureMap have an official (semi-official, for Autofac) mock framework integration example. Castle and Unity do not, however I was able to easily find appropriate samples. For Ninject and Spring.Net the containers are probably implementable, but I had no time to research it in detail.

Special features are very subjective, but two interesting things I noticed are contextual bindings in Ninject and container hierarchies in Autofac. Container hierarchies, in particular, seem to provide a solution for argument coupling. I will not describe these features in detail, however you may find it interesting to read about them.

Now special problems and pain points. In my opinion, Castle relies too much on “this is in trunk”. For example, Ayende has suggested me to use ResolveAll method to solve the generics problem I had with ResolveServices. However, there is no ResolveAll in RC3, as there is no fluent interfaces and other things. The problem with that is that I can not rely on specific version when discussing Castle with anybody, and I can not rely on having a tested and finalized version if I want to have new features.

I have not used Unity and Autofac in real work, but in tests I haven’t encountered any significant problems aside from unsupported features I already discussed.

In Ninject, there is a build problem under .Net 3.5 — sometimes I had to remove Ninject library from references and then re-add it, otherwise there was a build error about ExtensionAttribute defined twice. It was really annoying so I hope it will be fixed asap (or may be it already is).

With StructureMap, the most interesting discovery was that it is not limited to static classes. Until I was pointed to this fact, testing was quite painful, but now I can say I do not see any issues. Even better, it seems the this framework also provides an easy way to pass additional arguments by type, which is an easiest solution for argument-uncoupled factories.

Most problems with Spring.Net are based on the configuration complexity. The framework itself is powerful, but it would be nice to have autowiring and fluent configuration interface more visible in the documentation.

7. Conclusion

Judging from the comparison, I think my preferences for a new project lie between Autofac and Castle. Both frameworks understand the importance of good circular dependency resolution, and have a nice set of features. Right now I am considering Autofac, since I had a bad experience with Castle internals and hierarchical containers seem very promising. However Castle is much more mature framework, and Autofac probably has its downsides I just do not yet know about.

Ninject is probably also a good idea, I like its explicit modular system. However not being able to reliable build referencing projects on .Net 3.5 and no recursion handling are critical issues for me.

Unity is always a solid choice, it is well documented and well supported by Microsoft team. I disagree with its constructor choices and mandatory properties, but this may be less important for other people. No recursion handling here as well.

StructureMap is very interesting, since it has several surprising features that I was not expecting from any framework. For example, support for array resolution is a really neat step forward. The only important downsides of StructureMap I see now are recursion handling and constructor selection.

Spring.NET is probably the hardest choice with the most complex learning curve. It is powerful and extensible, but following the documentation it is very easy to end up with a large pile of hard-coded XML.

8. Tests and spreadsheets

To fill the gaps in the tables, I had to write some feature tests for the discussed frameworks.
MbUnit’s TypeFixture was invaluable for this purpose, since it allowed me to write each test exactly once.

You can get the test project and the complete spreadsheet here:

Code: Google Code
Spreadsheet: Zoho

The test project may also be useful to learn APIs of the reviewed frameworks.

kick it on DotNetKicks.com

Having some spare time and interest, I decided to learn a bit more about the features of modern .NET IoC frameworks. Being aware of what’s available always helps, and I haven’t yet seen a comprehensive feature comparison.

For the comparison, I have selected the frameworks that I feel to be most documented and popular:

If you feel that your framework should be here, just send me the values for all feature columns, and I’ll add it.

0. Terminology

The first thing I learned is that common concepts are sometimes named differently between the frameworks.

So I think it makes sense to start with some terminology.

Components are classes registered within the container. They can be instantiated by the container to satisfy service dependencies of other components. Services are what components provides and depends on.

In most of the cases services are interfaces, and components are classes implementing them.

Autowiring is an automatic detection of dependency injection points. If the framework is able to  match the constructor parameter types with registered services and provide these services, it is an example of autowiring.

Transient components, as compared to singletons, are created each time they are requested from container. The exact term used for transients differs quite much between frameworks.

Automatic registration is a way to automatically detect and register components within an assembly (or larger environment). It can also be called batch registration.

1. Licensing and core size

All reviewed frameworks work under .NET 2.0, and have liberal licenses allowing commercial and open-source usage.

The first table lists the reviewed frameworks with some basic parameters.

The color map is easy: green is great, yellow is ok, red is bad. All colors are extremely subjective, things bad for me may mean that I am doing something wrong.

I do not feel library count or size to be important for developments, so no red points this time.

Ninject is the most interesting case, since it has a very naive auto-wiring implementation by default. However, it has an official Ninject.Extensions.AutoWiring library, so in all following tables I included its features in Ninject functionality.

2. Container configuration

The first thing to do with container is to register something in it. So let’s review the configuration options provided by various framework.

As you can see, all frameworks support programmatic registration. Even better, most of them have fluent interfaces for registration API. Spring.Net and Castle are behind others in this regard, since Spring.Net API is somewhat cumbersome and not fluent, while Castle does not support fluent registration in RC3.

As I noted before, automatic registration is a way to register all types in given set of assemblies/namespaces based on attributes or other conventions. I find it very useful, since the convention-driven approach saves time on configuration and lessens a chance of a configuration error.

Castle’s BatchRegistrationFacility is obsolete and well-hidden, also it uses GetExportedTypes instead of GetTypes (The Sin of Shallow Digging), so it’s useless if you want to hide implementations and expose only interfaces. For Spring.NET I didn’t find an easy way, but it still might be possible, so you can correct me on this one.

Some people consider attributes to be POCO, some not, and I tend to agree with the latter when we are talking about DI frameworks. So no red points or yellow points if framework has no attributes, this column just for your information.

As for XML, I have a very strong opinion — only if actually needed, only as much as actually needed. Fortunately, no one of reviewed frameworks required XML (while most of them support it when needed). Spring.Net is somewhat differently oriented for this question, since its XML API is a better, more documented and encouraged approach. However, since Spring is a Java port, the approach is probably a compatibility heritage.

3. Basic injection/autowiring

The second thing after configuring the framework is knowing what exactly can be automatically injected. And, as I explained earlier, autowiring is just a name for framework-discovered injection points.

Basic constructor injection works great in all frameworks. For property injection Unity and StructureMap require explicit opt-in and treat the dependency as mandatory, which is a bit counterintuitive and does not provide any benefit over constructor injection.

As for multiple constructors, I really like the Castle/Autofac choice of constructor with most resolvable parameters. This is precisely what the human programmer will do, given a number of constructors and dependencies. With approach taken by Unity and StructureMap, it is harder to keep object DI-ignorant — you have to think whether your most-parameter constructor is resolvable, add DI-specific attributes or specify the constructor explicitly in the XML/code configuration.

The most interesting behavior was shown by the Spring.Net — it selected default (no-parameter) constructor first, and only if default did not exists, Spring went to the most resolvable.

Recursive dependency resolution is, in my opinion, one of the most important things in a DI framework. In a large project, when you have a lot of components and services, solving recursion easily is a must. In my tests only Castle and Autofac gave a useful error message, all other frameworks just crashed with unrecoverable StackOverflowException, which is a bad, bad thing to get in automatic test runner.

4. To be continued

In the second post of the series, I will review advanced features of DI containers (with StructureMap demonstrating unexpected feature), and show an automated feature tests I used to fill the blanks in these tables.

kick it on DotNetKicks.com

There is another feature that I do not find in the dependency injection frameworks I’ve seen — list injection.

For example, let’s suppose you have a kind of a notification service that sends messages using all possible delivery providers. It makes sense to have a list of these in the service:

public class NotificationService {
    private readonly IDeliveryProvider[] providers;

    public NotificationService(IDeliveryProvider[] providers) {
        this.providers = providers;        
    }

    public void SendAll(INotification[] notifications) {
        var deliveries = from notification in notifications
                         from provider in providers
                         from delivery in provider.GetDeliveries(notification)
                         select delivery;

        this.DeliverAll(deliveries);
    }
}

Now the problem is that there is no out-of-the-box support for such things in Castle, which is somewhat unexpected.

Yes, I can set arrays through configuration. But I never use XML configuration unless there is an extremely important reason for this to be configurable at deployment time, which does not happen very often with IoC containers. Also, documented approach implies that I have to hardcode a list of specific services here, which makes it a change preventer.

So configuration-only solution is out of the question.

Fortunately, in contrast with previous challenges, it is possible to implement this myself. There is a minor problem — Castle feature for getting an array of services (kernel.ResolveServices) is generic-only in RC3. But if I have to choose between hackarounds and using nameless trunk version, I prefer trunk version.

There is a naive version of the resolver:

internal class ListSubDependencyResolver : ISubDependencyResolver {
    private static readonly HashSet<Type> SupportedInterfaces = new HashSet<Type> {
        typeof(IEnumerable<>), typeof(ICollection<>), typeof(IList<>)
    };

    private readonly IKernel kernel;

    public ListSubDependencyResolver(IKernel kernel) {
        this.kernel = kernel;
    }

    public bool CanResolve(CreationContext context, ISubDependencyResolver parentResolver, ComponentModel model, DependencyModel dependency) {
        if (parentResolver.CanResolve(context, parentResolver, model, dependency))
            return true;
        
        var targetType = dependency.TargetType;      
        if (targetType.IsArray)
            return true;
        return targetType.IsInterface
            && targetType.IsGenericType
            && SupportedInterfaces.Contains(targetType.GetGenericTypeDefinition());
    }

    public object Resolve(CreationContext context, ISubDependencyResolver parentResolver, ComponentModel model, DependencyModel dependency) {
        if (parentResolver.CanResolve(context, parentResolver, model, dependency))
            return parentResolver.Resolve(context, parentResolver, model, dependency);
        
        var type = (
            from @interface in dependency.TargetType.GetInterfaces()
            where @interface.IsGenericType 
               && @interface.GetGenericTypeDefinition() == typeof(IEnumerable<>)
            select @interface.GetGenericArguments().First()
        ).Single();

        return this.kernel.ResolveAll(type, new Hashtable());
    }
}

Side note: here we can see two minor problems with API design — first one is the mysterious parentResolver (what should I pass as parentResolver to parentResolver?), second one is that shiny new ResolveAll has no overload for the case when I do not need additionalArguments.

This is a very naive implementation (no checks if I can actually resolve generic parameter), but it works quite well with the original case (as well as with the other IList/ICollection/IEnumerable requirements).

However, there is a logical consistency problem with Singletons — they will get different parameters depending on whether you have resolved them before registering all their dependencies or after. If a Singleton has such dependencies, it can not be Startable, unless you make sure to register all dependencies before it.

I have found almost no information on using lists with DI, so I am not sure how others solve this. But I do not need Startable and all my components are registered at almost same time, so this is not a problem for me for now.

Update: Thanks to Victor Kornov, I have found a this post by Castle developer, which describes the same solution. I have added a proposition to the corresponding Google Group to make it a built-in feature. I prefer it being enabled by default, but I would like to see it either way.

I am not sure what is the exact name for this pattern (probably Factory Method), but I often have a situation where I have to select a specific derived type based on some parameters.

For example, I may have a SyncFactory with CreateSync method that creates a Sync based on number of parameters.

public class SyncFactory {
    public ISync CreateSync(…) {
        if (…)
            return new FullSync(…);

        if (…)
            return new ExportSync(…);
        
        return new SimpleSync(…);
    }
}

This is a simplest situation. Now a realistic case may require synс operations to depend on some services.

Ok, let’s put them into a DI container and resolve them:

public class SyncFactory {
    // IResolver abstracts specific DI implementation
    // and the fact we are using DI. It is also mockable.
    public SyncFactory(IResolver<ISync> resolver) { … } 

    public ISync CreateSync(…) {
        if (…)
            return resolver.Resolve<FullSync>();

        if (…)
            return resolver.Resolve<ExportSync>();
        
        return resolver.Resolve<SimpleSync>();
    }
}

Up to now everything went quite smooth. But what if the factory needs to give some additional parameters to the syncs, like some SyncEndPoint?

With this in mind, I immediately stumble into two problems. First one is practical: how to pass parameters to the component being resolved? Second one is perfectionist: if components make no sense without these additional parameters, why should they be registered and available in a DI container?

I have been working with Castle IoC framework and I have found no good solution to both of these problems. First one can be solved by passing “additionalArguments” to Resolve methods, but this couples me to parameter names.

What I would like to do is to have some kind of local scope so I could do the following:

public class SyncFactory {
    public ISync CreateSync(…) {
        using (var endPoint = this.CreateEndPoint(…)) 
        using (var scope = new ComponentScope(endPoint)) {
            if (…)
                return resolver.Resolve<FullSync>();

            if (…)
                return resolver.Resolve<ExportSync>();
        
            return resolver.Resolve<SimpleSync>();
        }
    }
}

For second one, it makes sense to have a Create<T>() method on the container that does not require T to be registered, but does the same constructor discovery/creation as it does for registered components. Otherwise, we have to register useless components in the container, which leads to container pollution.

Unfortunately, Windsor/MicroKernel does not have this feature.

I am still not sure whether it’s me doing something the wrong way or argument coupling and container pollution are considered not that big of a deal. For me they seem to be a good feature test for DI Framework, and I am yet to see one with these fixed.