I have seen this line of code in several tutorials for using Unity in asp.net mvc3. I was under the impression that Service Locator is an anti-pattern and not best practice. Is this Service Locator something other than the anti-pattern defined, or is this line of code / this implementation considered bad practice.
ServiceLocator.SetLocatorProvider(() => new UnityServiceLocator(Container));
The purpose of the Service Locator pattern is to return the service instances on demand. This is useful for decoupling service consumers from concrete classes. An implementation will consist of the following components: Client – the client object is a service consumer.
Service Locator is a well-known pattern, and since it was described by Martin Fowler, it must be good, right? No, it's actually an anti-pattern and should be avoided.
To implement the IoC, you have the choice of two main patterns: Service Locator and Dependency Injection. The Service Locator allows you to "resolve" a dependency within a class and the Dependency Injection allows you to "inject" a dependency from outside the class.
The IoC container can be used as a service locator. Components that depend on a certain service can acquire the service using one of the GetInstance-methods.
Old question, but for the benefit of others:
While I absolutely agree with the mantra "Service Location is an anti-pattern", there are definitely exceptions to that rule.
When you use Dependency Injection (like Unity) then, yes, certainly don't use ServiceLocator and only use constructor injection for all your service classes. (Also don't use "new" for anything other than value objects like DTOs.)
However, there are cases where you simply can't use constructor injection and then the only way to get access to a service is to use a workaround to access your Unity container directly, and in such cases, ServiceLocator is a good standard way to accomplish that. This is the case when the class isn't instantiated by you (or more specifically, it isn't instantiated by Unity) but by the .NET framework for example.
A few simple examples of where ServiceLocator might be useful, is to get access to services registered in your Unity container from:
Note that this line is not ideal:
ServiceLocator.SetLocatorProvider(() => new UnityServiceLocator(Container));
The ServiceLocator.Current property is going to execute the delegate provided every time you access Current, i.e. a new UnityServiceLocator is going to get created every time. Instead, you probably want to do this:
IServiceLocator locator = new UnityServiceLocator(container);
ServiceLocator.SetLocatorProvider(() => locator);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With