5

They seem so similar. I can register something in the GlobalContainer:

GlobalContainer.RegisterType<TMyImplementation>.Implements<IMyInterface>;

And get an instance via GlobalContainer or ServiceLocator, both of them work:

MyInstance := GlobalContainer.Resolve<IMyInterface>;
MyInstance := ServiceLocator.GetService<IMyInterface>;
Rafael Piccolo
  • 2,328
  • 1
  • 18
  • 29

1 Answers1

6

The ServiceLocator is for resolving dependencies in your code when needed. There you don't want to use a reference to the container as that would be totally against the purpose of having losely coupled code.

Personally I agree with those that say that a service locator itself is an anti pattern and should be avoided whenever possible by injecting everything that is possible.

Stefan Glienke
  • 20,860
  • 2
  • 48
  • 102
  • Is ServiceLocator not there to abstract the DI framework? I use ServiceLocator combined with constructor injection. – whosrdaddy Feb 07 '13 at 09:58
  • Yes it is. However using that inside your code violates the tell don't ask principle. Using a ServiceLocator is not much better that having hardcoded constructor calls in your code. It trades the coupling to another class for coupling to the DI framework. First it was hard to write a unit test because of that hardcoded constructor call (no mock possible) now it is because you have to setup your di framework or write a mock for the service locator. – Stefan Glienke Feb 07 '13 at 10:12
  • I use 2 constructers per class, one where I put the dependencies (ie interfaces) and one without parameters and this one calls the other constructor with servicelocator. So for testing I can use the constructor with dependencies to inject my mocks. – whosrdaddy Feb 07 '13 at 10:15
  • I know the possible workarounds to make code testable. I could argue now why this is bad and you should not do that but I won't. I instead suggest you read some article or watch some presentation of Misko Hevery on this subject (like here http://misko.hevery.com/2008/11/11/clean-code-talks-dependency-injection/) and come to your own conclusion. Another good read is this blog article, why a service locator is an anti pattern: http://blog.ploeh.dk/2010/02/03/ServiceLocatorIsAnAntiPattern.aspx – Stefan Glienke Feb 07 '13 at 10:22
  • 1
    @stefan-glienke _"The ServiceLocator is for resolving dependencies in your code"_ -- and so is the GlobalContainer's `Resolve` method, what is the difference? _"There you don't want to use a reference to the container"_. So the `ServiceLocator` is nothing but a wrapper around `GlobalContainer` just to expose fewer methods? _"I agree with those that say that a service locator itself is an anti pattern"_ -- and isn't the `GlobalContainer` too, by the same reasons? – Rafael Piccolo Feb 07 '13 at 16:03