Design of the SharePoint Service Locator
The SharePoint Service Locator provides a lightweight, easy-to-use implementation of the service locator pattern. It is designed to do the following:
- It allows developers of consumer classes to decouple their classes from concrete implementations of interfaces.
- It allows developers of provider classes to register their classes as implementations of an interface, and to make these classes available to consumer classes across the application.
- It makes a single service locator implementation available throughout the farm or the site collection, which ensures that interface implementations are used consistently.
- It allows developers to substitute mock objects for dependencies, which facilitates isolated unit testing of classes.
- It allows developers to substitute alternative service locator implementations into the SharePoint Service Locator.
Design Highlights
The following class diagram illustrates the interrelationships between the key classes in the SharePoint Service Locator.
The SharePoint Service Locator
The main entry point to the service locator is the SharePointServiceLocator static class. This class creates and initializes instances of IServiceLocator, and exposes these service locator instances through the GetCurrent() method. The SharePoint Service Locator relies on an IServiceLocatorFactory implementation to instantiate an IServiceLocator implementation.
The SharePoint Service Locator also relies on the ServiceLocatorConfig class to store type mappings at both the farm and site collection levels. Service providers can use the RegisterTypeMapping method to register their service with the service locator. The ServiceLocatorConfig class persists these type mappings as site collection-level configuration settings if the Site property is set, or as farm-level configuration settings if it is not.
Note
The IConfigManager and IHierarchicalConfig interfaces shown in the diagram are part of the Application Settings Manager component. For more information on the Application Settings Manager, see the Application Setting Manager chapter in this guidance. The IServiceLocator and IServiceLocatorFactory interfaces are defined by the Common Service Locator library, as described in the following section.
Design Details
This section describes the design and functionality of the SharePoint Service Locator in more detail, including how the SharePoint Service Locator relates to the Common Service Locator project, which type mappings are registered by default, and how the SharePoint Service Locator actually creates service locator instances.
Relationship to the Common Service Locator
The IServiceLocator and IServiceLocatorFactory interfaces are defined by the Common Service Locator library, which is available on CodePlex. The goal of the Common Service Locator is to provide shared interfaces with binary compatibility for inversion of control (IOC) containers and service locators. The SharePoint Guidance team has not tested the use of any other service locator or IoC containers.
By default, the SharePoint Service Locator uses an IServiceLocatorFactory implementation named ActivatingServiceLocatorFactory. This class instantiates an IServiceLocator implementation named ActivatingServiceLocator. This relationship is illustrated by the following table.
Common Service Locator interface |
SharePoint Service Locator implementation |
---|---|
IServiceLocator |
ActivatingServiceLocator |
IServiceLocatorFactory |
ActivatingServiceLocatorFactory |
While the SharePoint Service Locator includes specific implementations of the Common Service Locator interfaces, you can substitute alternative implementations of these interfaces according to your application requirements. For more information on how to create your own IServiceLocatorFactory implementation to instantiate an alternative service locator, see Using a Custom Service Locator.
Note
You cannot use the ServiceLocator class from the Common Service Locator project in a SharePoint environment. The ServiceLocator class is designed to work with environments that expose a bootstrapping event when the application starts, such as the events within global.asax in an ASP.NET Web application. Because SharePoint does not expose similar events, the SharePoint Service Locator performs this initial bootstrapping when you call SharePointServiceLocator.GetCurrent(). If you attempt to set the SharePoint Service Locator instance using the ServiceLocator class, the SharePoint Service Locator will throw a NotSupportedException.
Creation of the Service Locator Instances
The IServiceLocator instances are created through the GetCurrent(), GetCurrent(SPSite), and GetCurrentFarmLocator static methods of the SharePointServiceLocator class. The service locator calls into an IServiceLocatorFactory implementation that creates and configures instances of IServiceLocator. This process works as follows:
- The SharePointServiceLocator class constructs the ServiceLocatorConfig object to retrieve the type mappings that are persisted to the configuration database in SharePoint property bags. Farm-scoped type mappings are retrieved only once and then cached.
- If applicable, the SharePointServiceLocator class also loads site collection-scoped type mappings. To do this, it constructs another ServiceLocatorConfig object and sets the Site property to the relevant SPSite object.
- To create an IServiceLocator instance, the SharePointServiceLocator class looks for the registered implementation of the IServiceLocatorFactory interface.
- If no custom IServiceLocatorFactory implementation is registered, the ActivatingServiceLocatorFactory class creates the IServiceLocator instance.
- If a custom IServiceLocatorFactory implementation is registered with the SharePoint Service Locator, the custom IServiceLocatorFactory implementation creates a new IServiceLocator instance. The IServiceLocatorFactory instance also populates the new service locator instance with the type mappings supplied by the ServiceLocatorConfig class.
The service locator instances are cached by the SharePointServiceLocator static class to improve performance. The farm-level service locator is loaded only once and cached. It only needs to be loaded once because deploying a farm level feature will cause the application domains to reload. As you update farm-scoped type mappings through a farm-scoped feature receiver, the application domain will be recycled and the new settings will be picked up when the service locator instance is reconstructed. As a result, it is safe to assume that the type mappings don’t change during the lifetime of the cached farm-level service locator instance.
However, this will not be the case for site collection-scoped type mappings, as these are deployed by site collection-scoped features. As a result the cached instances of the combined site collection and farm-level locators must be periodically refreshed. The configuration settings are checked periodically to see if any type mappings have been updated, and if necessary the service locator instance is refreshed with new type mappings.
Finally, the SharePoint service locator must also account for type mappings that are registered at runtime. When a farm-scoped type mapping is registered at runtime, the service locator receives an event. The service locator then updates each cached site collection service locator instance with the new type mapping.
Default Type Mappings
When you start to use the SharePoint Service Locator, you may notice that certain type mappings are already registered. In keeping with broader aspects of the SharePoint Guidance project, the service locator includes default type mappings for logging and configuration management. The following type mappings are registered by default:
- Logging. The ILogger interface is mapped to the SharePointLogger class. This logging implementation logs to the event log and to the Unified Logging Service (ULS), but this behavior can also be overwritten by registering custom type mappings for the IEventLogLogger or ITraceLogger interfaces.
- Configuration management. The IConfigManager and IHierarchicalConfig interfaces are mapped to the HierarchicalConfig class.
As with any type mappings, these default mappings can be overwritten by registering custom type mappings using the ServiceLocatorConfig class.
Error Handling
The SharePoint service locator raises an exception of type ActivationException if an error occurs during the process of service location. It may also raise .NET Framework exceptions for assembly and class load errors and exceptions of type NoSharePointContextException when a SharePoint context is required but not present.