What Does the SharePoint Service Locator Do?

Modular, test-driven code is central to the successful development of enterprise-scale applications. If you want to write code that is modular, pluggable, and fully compatible with automated unit testing, you need to employ a design pattern that enables you to remove dependencies on concrete types from your code. The Service Locator pattern is one such approach. Essentially, it maps interfaces to their implementations. Rather than using the concrete implementation directly in your code, you can simply request an implementation of an interface from the service locator, thereby decoupling your code from its dependencies. For more information on the Service Locator pattern, see The Service Locator Pattern.

Note

Service location is a specialized subset of the dependency injection pattern. For more information on dependency injection, see Unity Application Block on MSDN.

The SharePoint Service Locator is a simple, easy-to-use implementation of the Service Locator pattern. At the core of the SharePoint Service Locator is a dictionary of type mappings. Each dictionary entry maps an interface and an optional key string to the name of a class that implements the specified interface. The following table illustrates this. These type mappings are included by default to support other components in the SharePoint Guidance library.

Interface

Registered implementation class

ILogger

SharePointLogger

IHierarchicalConfig

HierarchicalConfig

IConfigManager

ConfigManager

When you need to use an external service in your code, rather than creating an object by invoking the constructor of a class, you can request an object with a specified interface from the service locator. The service locator looks up the interface in the dictionary, locates the corresponding implementation class, and returns an instantiated object to the caller.

For example, suppose that your class needs an implementation of the ILogger interface. You could instantiate a specific implementation of the ILogger interface in your code, as shown in the following diagram and code example:

Class with a direct dependency on a service

Ff798368.9114c474-6ab5-40fc-83b1-c6af9c4291a2(en-us,PandP.10).png

using Microsoft.Practices.SharePoint.Common.Logging; 

SharePointLogger logger = new SharePointLogger();

This approach has several drawbacks. For example, let’s say that your corporate policy changes and you need to enhance your logging functionality to take additional action on critical errors, beyond the default behavior of writing to the event log. If you want to replace the SharePointLogger class with an enhanced implementation of the ILogger interface, you must edit and recompile your consumer class. Also, as your consumer classes reference SharePointLogger directly, it's difficult to replace it with a mock object or a stub implementation of the ILogger interface for testing. Finally, you must ensure that the correct version of SharePointLogger is available at compile time.

In contrast, the service locator approach allows you to simply request the registered implementation of the ILogger interface. You do not need to know the details of the implementation. As a result, you can replace all the direct service dependencies in your class with a dependency on the service locator. The following diagram and code example illustrates this.

Class using the SharePoint Service Locator to retrieve a service

Ff798368.e991b18a-abc6-4910-9b97-94e995fc83a0(en-us,PandP.10).png

using Microsoft.Practices.ServiceLocation;
using Microsoft.Practices.SharePoint.Common.ServiceLocation;
using Microsoft.Practices.SharePoint.Common.Logging;

IServiceLocator serviceLocator = SharePointServiceLocator.GetCurrent();
ILogger logger = serviceLocator.GetInstance<ILogger>();

As you can see from the preceding code example, the SharePointServiceLocator class includes a static GetCurrent method that provides access to a service locator instance.

The service locator allows you to define type mappings at the SPFarm and SPSite configuration levels. You can therefore override the farm-level type mappings within a site collection if you want to provide a different behavior. For example, you may have a high security site collection where you want to save logged information out to a specialized auditing database as well. In this case, you could register a new logging service for the site collection, and provide an implementation that adds the additional auditing logic.

Note

You can use the service locator within sandboxed solutions. In this case, the service locator will only load type mappings from the site collection configuration level. However, the SharePoint Guidance library also includes a full trust proxy that allows sandboxed solutions to read configuration from the farm level. If this proxy is installed in the farm, the service locator will load type mappings from both the farm level and site collection level regardless of whether or not it is running in the sandbox.