I Love dependency Injection. It’s a great technique that can help you to build flexible and testable applications.
The SharePoint Service Locator
The SharePoint Guidance Library includes an implementation of the service locator pattern named the SharePoint service locator. The SharePoint service locator is a reusable component that you can include in your own SharePoint applications. It allows you to decouple consumers of an interface from the implementations of that interface. Instead of creating an object by invoking the constructor of a class, you request an object with a specified interface from the service locator. Decoupling your code from a concrete implementation makes your code easier to test and more modular.
The SharePoint ServiceLocator is a very handy component that allows you to achieve Inversion of Control. But it’s not a dependency Injection container such as Microsoft Unity.
When I was building the SharePoint ServiceLocator, I really wanted to use Microsoft Unity for it. Microsoft Unity is a great Dependency Injection Container. However, at that time, our advisors recommended that we should NOT use Unity, because it is quite complex. The advisors worried that most SharePoint developers would have a hard time understanding Unity.
The problem here is obviously, if you are unfamiliar with dependency injection as a technique, then using a very simple service locator is already a big step. However, if you are comfortable with dependency injection, then you can’t live without the capabilities that such a component provides.
Plugging Unity into the SharePoint ServiceLocator
When I was building the SharePoint ServiceLocator, I did keep in mind that someday I’d like to plug in a different dependency injection container, such as Unity. Now that I’m working for a company that’s actually using the SharePoint Guidance, I figured it would be time to create the components required to plug in Unity as a Dependency Injection Container.
As you can see, the SharePoint ServiceLocator is not the actual ServiceLocator…. It’s more of a ServiceLocatorLocator, but that name just sounds silly. But it does locate the actual ServiceLocator for you, which by default is the ActivatingServiceLocator.
Now what we want to do, is use Unity instead of using the Activating ServiceLocator. To do that, we need to create two components:
UnityServiceLocatorAdapterThe Unity container does not implement the IServiceLocator interface. This interface comes from the Common ServiceLocator project and has the goal to create a common interface that library builders can use abstract away dependencies from a specific DI container. So what we need, is an adapter that adapts Unity to the IServiceLocator interface. And the nice thing is.. that component already exists here.
But for completeness, here’s the source code for that:
Note that this class derrives from ServiceLocatorImplBase, which comes from the Microsoft.Practices.ServiceLocation.dll assembly (the common servicelocator project).
Secondly, we need a component that can acually create the UnityServiceLocatorAdapter and fill it with the typemappings that are stored in Config.
Here’s the source code for that component:
Configuring the SharePoint ServiceLocator to use the new factory
Now that we have both the factory and the adapter, we need a way to tell the SharePointServiceLocator to actually use these components. You simply do that by registering a typemapping between the IServiceLocatorFactory and the UnityServiceLocatorFactory from a farm scoped feature receiver, like this:
Changes you’ll have to make to the SharePoint Guidance Library
When we built the functionality to plug in different service locators, we tested of course if you could actually plug in a different service locator. And you can.. which is nice. However, we never had the time to actually create this Unity plugin. And since we never tried this.. it doesn’t work nicely out of the box.
So you’ll have to make 2 small changes to the library to get it to work nicely.
The first change I made is to remove the new() operator from all generic methods that create or register typemapings, such as the ServiceLocatorConfig.RegisterTypeMapping or TypeMapping.Create<>() methods. The new() operator defines that all physical classes that are used as typemappings have a default constructor. This seemed like a good idea with the ActivatingServiceLocator, but with unity, I like to use constructor injection, so the new() operator doesn’t make sense.
The second change was in the TypeMappings.Create<> method. I changed the ToType from the AssemblyQualifiedName of a type to the Full typename of a type. For some reason, on my machine, using the AssemblyQualifiedName doesn’t work. I don’t know what the reason for this is.. but using the Full typename works. So that’s something else I changed.
Hope you’ll find this useful.