The Simple Injector is an easy-to-use Inversion of Control library for .NET and Silverlight. It solely supports code-based configuration and is an ideal starting point for developers unfamiliar with larger IoC / DI libraries.
Readers that are already familiar with the Simple Service Locator might be wondering what happened with it. Nothing has happened with it. I released a stable release over a month ago and you can still download it.
The Simple Injector is a fork of the code base of the Simple Service Locator and shared almost the exact same API as the Simple Service Locator. There is a reason however, why I renamed the Simple Service Locator.
In earlier posts (here and here) on my blog, I question the usefulness of the Common Service Locator and keyed registrations. I decided that I didn’t want to remove those features from the Simple Service Locator, because it could annoy existing users. I had however, strong reasons to remove those, because I didn’t feel those features did belong there.
Because I wanted to introduce some major breaking changes, such as removing the hard dependency on the Common Service Locator and the removal of keyed registrations, I decided to change the name of the new version. This has a few advantages. First of all, this communicates clearly that this is not the Simple Service Locator and users should not expect it to be compatible. Besides this, the name of the Simple Service Locator was chosen, because it is an implementation of the Common Service Locator. Since I removed the dependency with the Common Service Locator, there was no reason to call the library ‘Simple Service Locator’, which was a controversial name in the first place. It lead to a lot of confusion.
Because of the above, I ‘rebranded’ the library, which is now called ”Simple Injector”. I will still maintain the Simple Service Locator, but the focus of development and documentation lies with the Simple Injector. You can see the Simple Service Locator as feature complete. It’s done, just like LINQ to SQL is ‘done’ :-).
So what are the differences with the Simple Service Locator anyway?
1. No more Common Service Locator
Like I said, I removed the dependency on the Common Service Locator (CSL). This means that you don’t need the Microsoft.Practices.ServiceLocation.dll anymore. If you still want to hide the Simple Injector behind the CSL façade, you still can. There is now an CSL Adapter available in the download.
2. No more keyed registrations
Second difference is the removal of the keyed registrations. Keyed registrations make sense in two situations. It makes sense when you are calling into the container itself directly from within your application, and second, it makes sense when using keyed registrations for registration purposes. Some DI containers contain many examples in their documentation were keyed registrations are used for things as decorators or collections of instances.
The thing is however, that calling into the container itself is a pattern known as the Service Locator pattern, and is typically considered an anti-pattern. I agree with this and it is the main reason for me changing the library so drastically.
The containers that use keyed registrations as examples are mostly the containers that do not allow concrete unregistered types to be resolved (such as Autofac and Castle Windsor). Simple Injector (or Simple Service Locator for that matter) allow unregistered concrete types to be resolved (just as Unity and StructureMap do). The reason for those other frameworks not to do this by default, is because it is considered bad practice to depend on concrete implementations. I agree with that, but this doesn’t mean you shouldn’t be able to resolve a concrete type if you want to. In fact, allowing concrete instances to be resolved, it makes the actual DI configuration much simpler, and that’s really what the Simple Injector is all about. I haven’t found a scenario yet that could only be solved by using keyed / named registrations with the Simple Injector. Because of all this, I simply had to remove it from the library. If you really want to be able to resolve an instance by a key though, just create an abstract factory. It’s so simple to do so, that this by itself justifies not having such a feature in the library.
Besides these two changes, there are other changes, such as Silverlight support. While Simple Service Locator always intended to have Silverlight support, it didn’t really work. I pulled the support from the stable release of the Simple Service Locator. To get this to work in the Silverlight sandbox, was actually quite a lot of work. Simple Injector now supports Silverlight (and the solution now has a full set of unit tests for Silverlight, that will ensure that it will keep working).
4. Extensions for more advanced stuff
Simple Injector now contains an Extensions assembly, that can be added when you want advanced features. The project existed in the Simple Service Locator source code, but it just contained a bunch of example code snippets. For Simple Injector, that project is now fully tested and part of the download. Placing this stuff in a separate assembly, allows the core to be really slim and easy to grasp.
5. Good support for property injection
The Simple Service Locator contains Register<TConcrete>(Action<TConcrete>) and RegisterSingle<TConcrete>(Action<TConcrete>) overloads that allow registering a concrete type and hook up an Action<T> delegate that allow initializing that type after it is created. Unfortunately, this only works with concrete types. In the Simple Injector project these methods are replaced with a single RegisterInitializer<T>(Action<T>) method. This method allows registration of delegates for each and every type. For instance, when you hook up an Action<object> delegate, it will be called for each and every instance created by the container. While this might not be that useful, it shows the power of this feature. The main scenario for this feature is property injection. The feature allows to register a delegate for a base type, and it will run after the creation of every type that derives from it (or implements it, if it's an interface). There is one catch though, with this feature. While this feature has a one-to-one mapping for some DI frameworks (such as Autofac), you can have a hard time doing this with others (such as Castle Windsor and Unity). I am writing a migration guide, which helps users that want to switch from Simple Injector to another DI framework. I will describe the lack of support for this feature on the migration page of those frameworks that do.
I hope developers find the library useful. My intention is to keep it small and simple, and having lots of documentation and code snippets on the CodePlex wiki to keep developers productive.