Service Locator vs. Dependency Injection
Asked Answered
G

4

6

I'm reviewing code with a lot of statements like this:

private SomeInterface x = Locator.getInstance(SomeInterface.class)

I would expect something like

private SomeInterface x;

@Inject
public Consumer(SomeInterface x){ // constructor
    this.x = x;
}

Is there something wrong with the first approach? Ok, dependencies are not so obvious, but implementations could easily be swapped through configuration of Locator.

Glyn answered 9/6, 2011 at 10:23 Comment(1)
steveschols.wordpress.com/2012/05/14/…Peele
P
11

Martin Fowler wrote an article on DI versus Locators:

For DI:

  • Easier to determine what dependencies a component has - look at constructor.
  • Component does not have dependency on Service Locator so there is not a problem if the component is used with a different framework.
  • DI may make testing easier but a good Service Locator mechanism will make stubbing equally feasible

Against DI:

  • Harder to debug and understand.
  • Component cannot request extra services from injector once it had been configured.

I personally don't think there's anything inherently bad with the first locator based approach - I guess DI does standardise this though, so if it's available I would use it. All good ideas tend to end up as frameworks at some point, so this has what's happened here. Plus with DI you can take advantage of other annotations, scopes, etc. without having to roll your own code. And the less bespoke code your project uses the better IMO. I'll leave the last word to Fowler though:

The choice between Service Locator and Dependency Injection is less important than the principle of separating service configuration from the use of services within an application.

Pratt answered 9/6, 2011 at 10:31 Comment(0)
C
6

First example : x = Locator.getInstance(SomeInterface.class) is looks like Service Locator pattern, and http://blog.ploeh.dk/2010/02/03/ServiceLocatorIsAnAntiPattern.aspx check this article it says Service Locator is an anti-pattern and should be avoided

And for the second usage its all fine i like Constructor Injection, its smooth fine implementation. But I would like to not to use Attributes ( annotanitons in Java?) cause anytime i might want to change DI container i am using and i dont want to remove an attribute from all classes.

Click answered 9/6, 2011 at 10:29 Comment(3)
@Inject is standardized in Java by JSR-330Glyn
@Glyn I thought it was just CrazyBob's DI's annotation. Didnt know it was accepted as Language standart. Thanks for the info.Click
Also: Contexts & Dependency Injection for Java (CDI) defined in JSR 299, JSR 346, and JSR 365. Now maintained at Jakarta.ee as Jakarta Contexts and Dependency Injection.Kirven
D
2

Service locator pattern uses a central registry known as the "service locator" which on request returns the information necessary to perform a certain task.

These are the worst sides of Service Locator Design Pattern:

  • Things placed in the registry are effectively black boxes with regards to the rest of the system. This makes it harder to detect and recover from their errors, and may make the system as a whole less reliable.

  • The registry must be unique, which can make it a bottleneck for
    concurrent applications.

  • The registry can be a serious security vulnerability, because it allows outsiders to inject code right into an application.

  • Can't pass dependencies by constructor (as we do in DI pattern) and hard to unit-test

And I my opinion using service locator design pattern is acceptable only on top level of your application when your service locator probably will not change

Decontrol answered 2/11, 2012 at 3:43 Comment(0)
N
1

There's nothing "wrong" as such with the service locator pattern,

In this particular case, the one major argument in favor of DI would be testability.

Without a doubt, DI allows for better unit testing. The static getInstance method on Locator makes it more difficult to test in isolation.

Nard answered 9/6, 2011 at 11:48 Comment(3)
There is more to it than only unit testing. Mark Seemann has described this very clearly: blog.ploeh.dk/2010/02/03/ServiceLocatorIsAnAntiPattern.aspx.Floodlight
Wanted to avoid these type of philosophical discussions :) “Anti-Pattern” is an over used statement IMHO. I'm personally also in favor of DI, but I would't go as far as to mark it as an anti pattern during a code review.Nard
I introduced IoC (in the form of the service locator pattern) a few years back on a project to allow that team to start writing tests. It was a good start from not being able to test at all. But now, more than two years later, having this pattern all over the place instead of using DI is a real real pain. So for me it is not philosophical anymore. I've been there, I experienced it, and it was all my fault. These days I try to scream as load as I can to help others from making the mistake I made.Floodlight

© 2022 - 2024 — McMap. All rights reserved.