Search code examples
springdesign-patternsdependency-injectiontype-safetyyellow-pages

Questioning Dependency Injection through name-lookup


I find myself struggling with the fuzz around the concept of string-based 'Service Locators'.

For starters, IoC is great, and programming to interfaces is the way to go. But I fail to see where the big benefit lies in the yellow-pages pattern used here, apart from compilation-less reconfigurability .

Application code will use a (Spring) container to retrieve objects from. Now that's nice: since the code needs to know only the needed interface (to cast to), the Spring container interface, and the name of the needed object, a lot of coupling is removed.

public void foo(){
   ((MyInterface) locator.get("the/object/I/need")).callMe();
}

Where, of course, the locator can be populated with a gazillion of objects of all kind of Object derivatives.

But I'm a bit puzzled by the fact that the 'flexibility' of retrieving an object by name actually hides the dependency in a type-unsafe, lookup-unsafe manner: where my compiler used to check the presence of a requested object member, and it's type, now all of that is postponed to the runtime phase.

The simplest, functionally allright, pattern I could think of is a giant, application wide struct like object:

public class YellowPages  {
    public MyInterface the_object_i_need;
    public YourInterface the_object_you_need;
    ....
}

// context population (no xml... is that bad?)
YellowPages locator = new YellowPages();
locator.the_object_i_need=new MyImpl("xyx",true),
locator.the_object_you_need=new YourImpl(1,2,3)


public void foo(){
   locator.the_object_i_need.callMe(); // type-safe, lookup-safe
}

Would there be a way/pattern/framework to ask the compiler to resolve the requested object, and check whether it's type is ok? Are there DI frameworks that also do that?

Many thanks


Solution

  • What you are describing is an anti-pattern, plain and simple. Dependency injection (done via the constructor if possible) is the preferred way to do Inversion of Control. Older articles on IOC talk about service location as a viable way to implement the pattern, but you'd be hard pressed to find anyone advocating this in more recent writings.

    You hit the nail on the head with this statement:

    But I'm a bit puzzled by the fact that the 'flexibility' of retrieving an object by name actually hides the dependency in a type-unsafe, lookup-unsafe manner:

    Most modern DI frameworks can get around the type-unsafe part, but they do hide the dependency by making it implicit instead of explicit.

    Good article on this topic:

    Service Locator is an Anti-Pattern