Service locator pattern and DDD
-
28-10-2019 - |
Question
I have a framework with a DDD data layer which uses the service locator pattern. However, currently I use a global static ServiceLocator
class which stores all the references. I would like to refactor this into a correct implementation where classes implement the IServiceProvider
interface and where I remove the global static ServiceLocator
class.
Now, almost everywhere it isn't issue to extend existing classes with the IServiceProvider
interface, except for the entity classes. The problem is that I would think it very strange for the entity classes to have to implement IServiceProvider
, but I do need a way to access a service provider to be able to resolve repositories through my IoC container.
What would be the best way to implement the service locator pattern without having to implement IServiceProvider
on my entities?
Solution
Why the heck would an entity (business object) expose IServiceProvider? It is a business object, not a service. And IServiceProvider is not even for services, it is an IOC mechanism to expose service providers.
if anything, your ORM / business object framework / runtime is a service provider, but not the individual entities.
let me return the question: I dont see any sensible programming concept where entities expose IServiceProvider to start with.
---update
Services only should provide a service locator - and you should have one. You can use thread static variables for those cases where defined threads access elements (name: UI for example - UI elements must be accessed by spec by the UI thread) which breaks the global singleton.
OTHER TIPS
A Service Locator is best used in combination with an Inversion of Control container such as Unity, Castle Windsor or NInject. See http://commonservicelocator.codeplex.com/wikipage?title=Unity%20Adapter&referringTitle=Home&ProjectName=commonservicelocator for an example of a service locator that works with Unity.
And remember that Service Locator can be seen as an antipattern -- it should be used very carefully. It is much better to use constructor or property injection instead. But in cases where the dependencies are very much dependent on the functionality being executed, Service Locator has a place.