Service Locator Pattern in C#: A Simple Example

A Service Locator is a common design pattern that allows decoupling clients of services (described by a public interface) from the concrete class implementing those services. Martin Fowler has a great introduction on the topic in his Inversion of Control Containers and the Dependency Injection pattern.

What follows is a very simple service locator implementation in C# based on generics.

Let’s start defining the contract of a service locator.

public interface IServiceLocator
{
    T GetService<T>();
}

Now let’s see a very simple implementation of this contract:

class ServiceLocator : IServiceLocator
{
	// map that contains pairs of interfaces and
	// references to concrete implementations
	private IDictionary<object, object> services;

	internal ServiceLocator()
	{
		services = new Dictionary<object, object>();

		// fill the map
		this.services.Add(typeof(IServiceA), new ServiceA());
		this.services.Add(typeof(IServiceB), new ServiceB());
		this.services.Add(typeof(IServiceC), new ServiceC());
	}

	public T GetService<T>()
	{
		try
		{
			return (T)services[typeof(T)];
		}
		catch (KeyNotFoundException)
		{
			throw new ApplicationException("The requested service is not registered");
		}
	}
}

As you can see,

  • the constructor of the class registers all the available services in a dictionary. In our example, we have 3 different services accessible through IServiceA, IServiceB, and IServiceC. It is assumed here that ServiceA implements IServiceA and so forth.
  • the generic GetService() method returns a reference the correct implementation fetching it from the dictionary

This is how a client would invoke the service:

IServiceLocator locator = new ServiceLocator();
IServiceA myServiceA = locator.GetService<IServiceA>();

The clients do not know the actual classes implementing the service. They only have to interact with the service locator to get to an implementation.

Improvements

This is as simple as it gets. There are several improvements that a real-world implementation of a service locator should consider (what follows is only a partial list):

  • The service locator itself might be a singleton. There usually is no need to have two instances of a service locator.
  • Lazy initialization of services might be considered. In the example above, the constructor creates new instances for all possible services; initialization might be deferred until some client actually requests a particular service.
  • The mapping between interfaces and implementation might be more flexible using metadata (e.g. through application configuration files)

Next article in the series: Service Locator Pattern in C# with Lazy Initialization

Bookmark and Share

Technorati Tags: , , ,
This entry was posted in Design and Patterns and tagged , , , . Bookmark the permalink.
  • Pingback: Service Locator Pattern in C# with Lazy Initialization « Stefano Ricciardi's Blog

  • http://www.moldremoval.net/ Mold Testing Moreno Valley

    Thanks for the this article.

  • http://twitter.com/joshuaRam Joshua Ramirez

    I completely agree with your point on providing lazy initialization of services as an improvement. For even moderately complex system, this becomes highly desirable. This is especially true when working with expensive objects which hold unmanaged resources.

  • Adriano Trevisan

    Great post. Thanks.

  • http://twitter.com/RainerHilmer RainerHilmer

    That’s all? Gee I thought a service locator is something complicated. :-D
    Thanks for the article. That’s one for my archive.

  • http://robertcoulston.myopenid.com/ Robert Coulston

    Very simple and easy to follow…thanks

  • http://kresimirbojcic.com Kresimir Bojcic

    Hey this is a cool implementation with generics…

  • Ravichandra2004

    Good example i have seen so far.

  • Anonymous

    Glad you liked it!

  • Cshira01

    ????, ?????? ?????? ?????!

  • None

    I like the way you’ve kept this on topic, and then later on in the article, specified how you can improve the implementation through lazy instantiations, and having a singleton for the service instance. I read this article and implemented it for a very simple product console app and it works, thanks again for the article

  • Giacomo Stelluti Scala

    It may be secondary. But why I Dictionary[object, object] instead of Dictionary[Type, object]?
    There’s some special reason?

  • stefanoricciardi

    Giacomo,
    no particular reason.

    In fact, if you follow through the subsequent posts in the series, you will see that that Dictionary will change to something different.
     
     Stefano

  • http://www.facebook.com/uialberto Luis Alberto Baigorria Rodas

    Very Good!. Excuse Me. I have this problem:

    ServiceA –> IReader
    ServiceB –> IReader
    ServiceC –> IReader

    IServiceLocator locator = new ServiceLocator();
    IReader Ineed_servicioA = locator.GetService();

    ???

  • Salvo

    Beautiful article, great! :-)