Click here to Skip to main content
Click here to Skip to main content
Go to top

Common Service Locator: Separate hard reference of your IoC/DI container from your solution

, 11 Jan 2010
Rate this:
Please Sign up or sign in to vote.
How to use Common Service Locator to lose dependency of your project on IoC container.

Service Locator 

Dependency Injection is a way to separate dependency. Someone can use Constructor Injection, Setter Injection, etc. for injecting dependency. Service Locator solves the same problem as Dependency Injector but it uses a different approach. Service Locator holds reference of all types/objects an application needs. So whenever you need to use an instance of a type/class, ask service locator to provide the instance. Simply, the Service Locator uses a container to hold all references to class/type to instance/object mapping. You can follow the links for details:

Why Common Service Locator? 

Nowadays as a .NET developer, we have a set of DI/IoC containers to choose from. We have option for Sprint.NET, Unity Application Block, Castle Windsor etc. Whenever you use any of them in your project, the project is tightly coupled with that container. So if you start your project with Sprint.Net Container then your project will be tightly coupled with the Spring.Net container. But later if you decide to use Unity Application Block, then can you imagine how many hassles are waiting for you? You need to remove all references of Spring.Net container from your code. Another example might be, you are developing a library that will be used by other users. Now if you use a IoC Container (say Sprint.Net), then you are forcing users to use Sprint.Net whenever they want to use the library. So if it would be possible to lose the coupling between your code and the IoC container, then you can easily remove dependencies on IoC container.The Common Service Locator project at CodePlex is aimed to attain the goal.

Use Common Service Locator  

1. Get an understanding of IServiceLocator interface

Start with an Interface IServiceLocator which has a few methods which are generic to any IoC container.The IServiceLocator inherits from IServiceProvider.

public interface IServiceProvider
{
    object GetService(Type serviceType);
}

public interface IServiceLocator : IServiceProvider
{
    object GetInstance(Type serviceType);
    object GetInstance(Type serviceType, string key);
    IEnumerable<object> GetAllInstances(Type serviceType);
    TService GetInstance<TService>();
    TService GetInstance<TService>(string key);
    IEnumerable<TService> GetAllInstances<TService>();
} 

The Common service Locator will implement the interface IServiceLocator. The Common Service Locator framework has provided an abstract implementation of IServiceLocator called ServiceLocatorImplBase. The ServiceLocatorImplBase has two abstract methods which actually depends on IoC Container.

  • DoGetAllInstances: Get all instances of a particular type from Container
  • DoGetInstance: Get a particular instance from Container

For getting instance from container, ServiceLocatorImplBase uses the above two methods. And those two methods are implemented by derived class. And Container is actually needed by those two methods. So Container is specific to individual implementation.

2. Develop your custom Service Locator 

I have developed two service Locators for Unity and Spring.Net. UnityServiceLocator can use Unity containers whereas Sprint.Net can uses Object Factory. The following class diagram shows two implementations that I have developed in the project attached with this post.

image

Figure 1: Two sample implementations of Common Service Locator 

3. Develop BootStrapper 

So I have developed two service locators till now. Now I need to develop two bootstrappers for Spring.Net and Unity as type registration are different for two.

public abstract class CommonBootStrapper
{
    public static IServiceLocator Locator;

    protected CommonBootStrapper()
    {
        Locator = CreateServiceLocator();            
    }

    protected abstract IServiceLocator CreateServiceLocator();
} 

The common bootstrapper has an instance of IServiceLocator which means it can hold reference to any class’s instance inheriting from ServiceLocatorImplBase (as ServiceLocatorImplBase implements IServiceLocator). So we can put the UnityServiceLocator or SpringServiceLocator in the CommonBootStrapper’s Locator variable. Now we need two different bootstrappers for Unity and Spring.Net. The Unity implementation is shown below:

public class UnityBootStrapper : CommonBootStrapper
{
    protected override IServiceLocator CreateServiceLocator()
    {
        UnityContainer container = new UnityContainer();
        RegisterTypes(container);
        return new UnityServiceLocator(container);
    }

    private static void RegisterTypes(IUnityContainer container)
    {
        container.RegisterType<ICustomer, GoldenCustomer>(typeof(ICustomer).FullName);
    }
} 

As shown in the code above, the UnityBootStrapper needs to override the CreateServiceLocator and in this method I have created a UnityContainer and packed it within UnityServiceLocator. For Spring.Net, you can create a SprintServiceLocator with ObjectFactory packed in it.

4. Develop a BootStrapper Manager to provide a single point of access to Service Locator

Finally you need to develop a bootstrapper manager to hide the concrete implementation of CommonBootStrapper. The following code shows the BootStrapperManager:

public class BootStrapperManager
{
    private static CommonBootStrapper _bootStrapper;


    public static void Initialize(CommonBootStrapper bootStrapper)
    {
        _bootStrapper = bootStrapper;
    }

    public static CommonBootStrapper BootStrapper
    {
        get { return _bootStrapper; }
    }
} 

5. Access the IServiceLocator through BootStrapperManager 

Now you need to register your BootStrapper to BootStrapperManager at some entry point to your application (like Main method). I have registered as shown below:

BootStrapperManager.Initialize(new UnityBootStrapper());  

Now from the application, I only use CommonBootStrapper.Locator to get the IServiceLocator instance. So to get any instance from container, I can write code like below:

ICustomer customer = CommonBootStrapper.Locator.GetInstance<ICustomer>
	(typeof(ICustomer).FullName);
customer.SendMessage("This is me."); 

Conclusion 

I have just gone through some basic ideas on how you can use Common Service Locator to decouple dependency to IoC Container from your production code. You can get more details on this by visiting the CodePlex link. For making my implementation, I have included the source code from Common Service Locator in my Visual Studio Solution.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Sohel_Rana
Architect ImpleVista Aps
Denmark Denmark
Sohel has more than six years of experience in professional software development with extensive involvement in Web based Object-Oriented, Multi-Tiered application design and development. He's Familiar with Test Driven Development (TDD) and refactoring techniques as well as having expertise in architecturing large enterprise applications. He has Experience in working with Content Management System and Portal Management System tools like SharePoint, DotNetNuke, Ektron.
 
Over last few years, he’s involved in development with projects on Microsoft SharePoint and received Microsoft MVP for SharePoint Server Development in the year 2011 and 2012. Currently he's working in a software company located Copenhagen,Denmark on a project integrating SharePoint and SAP. You can read his popular blog at: http://ranaictiu-technicalblog.blogspot.com

Comments and Discussions

 
QuestionStill don't get it Pinmemberabjr18-Nov-12 3:32 
GeneralNice article Pinmemberalberto-sa15-Sep-10 10:56 
GeneralPrism PinmemberCristian Odea13-Jan-10 20:42 
GeneralRe: Prism PinmemberSohel_Rana13-Jan-10 21:19 
This is not the one used in Prism and the code I have used is a kind of modification from codeplex link ^]

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web04 | 2.8.140922.1 | Last Updated 11 Jan 2010
Article Copyright 2010 by Sohel_Rana
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid