The SharePoint Service Locator is a reusable component from
the MS Patterns & Practices that provides a simple implementation of the
service locator pattern. You can use it in your own SharePoint applications to
decouple the consumers of an interface from the implementations of that
interface. Instead of creating an object by invoking the constructor of a
class, you request an object with a specified interface from the service
locator. The service implementation can now be replaced or updated without altering
the consuming class implementation.
The usage of service locator makes it easy to dependencies
that are scattered throughout various projects and solutions. These
dependencies often make it challenging to maintain code over time—if you modify
one class, you must recompile every project that references that class. This
also makes unit testing code in isolation much more complicated. In short,
decoupling your code from specific types makes your code more modular, easier
to manage, and easier to test.
You can use the RegsiterTypeMapping
method of the ServiceLocatorConfig
instance to register the mappings to the service locator.
var serviceLocator = SharePointServiceLocator.GetCurrent();
var mappingsConfig = serviceLocator.GetInstance<IServiceLocatorConfig>();
mappingsConfig.RegisterTypeMapping<IMyService, MyService>();
You can retrieve the interface implementation later in your
code using the GetInstance method of the ServiceLocatorConfig instance.
serviceLocator.GetInstance<IMyService>();
Normally you register the instances during the feature activating
event and you need to remove the registered mappings from the service locator
during feature deactivating event using the remove mappings method.
var serviceLocator = SharePointServiceLocator.GetCurrent();
var mappingsConfig = serviceLocator.GetInstance<IServiceLocatorConfig>();
mappingsConfig.RemoveTypeMapping<IMyService>(null);
Unit
testing challenge – Replacing the ServiceLocator in the test context
The service locator from the P&P uses the sharepoint
object model to keep store of the mappings and other properties. To
successfully unit test the code that uses the service locator, you need to
either use a wrapper object for the service locator or use the ActivatingServiceLocator object
instead of the ServiceLocator in
the test code.
To replace the service locator instance, you need to replace
the actual service locator with the ActivatingServiceLocator
instance as given below.
var activatingServiceLocator = new ActivatingServiceLocator();
SharePointServiceLocator.ReplaceCurrentServiceLocator(activatingServiceLocator);
const string type1 = "Type1";
const string type2 = "Type2";
activatingServiceLocator.RegisterTypeMapping<INotRegisteredType, NotRegisteredType1>(type1);
activatingServiceLocator.RegisterTypeMapping<INotRegisteredType, NotRegisteredType1>(type2);
var notRegisteredType = SpServiceLocator.GetInstance<INotRegisteredType>(type1);
Assert.IsInstanceOfType(notRegisteredType,
typeof(NotRegisteredType1));
SharePointServiceLocator.Reset();
2 comments:
I noticed you have posts on this, as well as the SharePoint emulator. Have you run into this issue?
http://stackoverflow.com/questions/23483212/how-do-i-use-sharepoint-emulator-with-sharepoint-service-locator
When my team and I try to retrieve the replaced/current service locator within an enabled emulation scope, we get an error that the SPFarm was not found. We also have not had any success in shimming the SPFarm object.
If you've seen this, how were you able to resolve it?
I noticed you have posts on this, as well as the SharePoint emulator. Have you run into this issue?
http://stackoverflow.com/questions/23483212/how-do-i-use-sharepoint-emulator-with-sharepoint-service-locator
When my team and I try to retrieve the replaced/current service locator within an enabled emulation scope, we get an error that the SPFarm was not found. We also have not had any success in shimming the SPFarm object.
If you've seen this, how were you able to resolve it?
Post a Comment