This content is outdated and is no longer being maintained. It is provided as a courtesy for individuals who are still using these technologies. This page may contain URLs that were valid when originally published, but now link to sites or pages that no longer exist. |
You have classes that have dependencies on services whose concrete type is specified at design time. In this example, ClassA has dependencies on ServiceA and ServiceB. Figure 1 illustrates this.
Figure 1 ClassA has dependencies on ServiceA and ServiceB
This situation has the following constraints:
Any of the following conditions justifies using the solution described in this pattern:
Create a service locator that contains references to the services and that encapsulates the logic to locate them. In your classes, use the service locator to obtain service instances. Figure 2 illustrates this.
Figure 2 ClassA uses the service locator to get an instance of ServiceA
The service locator does not instantiate the services. It provides a way to register services and it holds references to the services. After the service is registered, the service locator can find the service.
Note: |
The service locator should provide a way to locate a service without specifying the concrete type. For example, it could use a string key or a service interface type. This enables easy replacement of the dependency concrete implementation without modifying your classes' source code. |
The Service Locator pattern can be implemented in several ways. The Unity Application Block provides a container that can be used as a service locator. For more information about the Unity Application Block, see Unity Application Block.
The following code, extracted from the NewsModule class of the Stock Trader Reference Implementation (this class is located at StockTraderRI.Modules.News\NewsModule.cs), shows how an instance that implements the INewsController interface is obtained using the service locator pattern. The variable _container holds an instance to a Unity container that has logic to locate a valid instance of the requested type.
C#
public void Initialize(){ RegisterViewsAndServices(); INewsController controller = _container.Resolve<INewsController>(); controller.Run();}
Note that for testing purposes, you could configure the container to return a mock instance that implements the INewsController interface instead of the real implementation. This enables you to test the NewsModule class in isolation. The following code, extracted from the NewsModuleFixture test class (located at StockTraderRI.Modules.News.Tests\NewsModuleFixture.cs), shows how the NewsModule class can be tested in isolation using a mock instance for the INewsController interface.
C#
[TestMethod]public void InitCallsRunOnNewsController(){ MockUnityResolver container = new MockUnityResolver(); var controller = new MockNewsController(); container.Bag.Add(typeof(INewsController), controller); var newsModule = new NewsModule(container); newsModule.Initialize(); Assert.IsTrue(controller.RunCalled);}
The Service Locator pattern has the following liabilities:
The following patterns are related to the Service Locator pattern: