34

On the Wikipedia page on dependency injection, the disadvantages section tells us this:

Dependency injection increases coupling by requiring the user of a subsystem to provide for the needs of that subsystem.

with a link to an article against dependency injection.

Dependency injection makes a class use the interface instead of the concrete implementation. That should result in decreased coupling, no?

What am I missing? How is dependency injection increasing coupling between classes?

4
  • 2
    I'm not sure who wrote that list of disadvantages, but I'd take it with a grain of salt. For example, I've seen DI reduce the size of a code base by 2/3 by eliminating a ton of redundant set-up code.
    – sea-rob
    Jun 4, 2014 at 14:53
  • @RobY I mostly used factory to inject the dependency, and my experience is that it increases the code size, but simplifies testing. Jun 4, 2014 at 15:22
  • Try using an alternative like Registry or Context Passing ;) Or else code that just instantiates objects and then pulls their properties from config. Mainly, I'm talking about the difference between now and 15 years ago.
    – sea-rob
    Jun 4, 2014 at 15:24
  • Related: stackoverflow.com/a/9503612/264697. Mark Seemann's answer explains how overall coupling is reduced using Dependency Injection.
    – Steven
    Nov 21, 2014 at 12:07

3 Answers 3

45

So, what am I missing?

Dependency Injection decreases coupling between a class and its dependency. But it increases the coupling between a class and its consumer (since the consumer needs more info to create it) and the dependency and its consumer (since the consumer needs to know the dependency to use).

Very often, this is a good trade off. The class shouldn't know the details about its dependencies beyond an interface, and it should be the responsibility of the application to tie specific bits of code together.

4
  • Right, coupling is decreased one way and increased another. Jun 5, 2014 at 3:52
  • But the consumer doesn't create it; that's rather the point.
    – Casey
    Jun 5, 2014 at 16:49
  • @emodendroket - Eh? Inversion of Control lets the consumer not create it. Dependency Injection is orthogonal to that.
    – Telastyn
    Jun 5, 2014 at 18:58
  • Well, you're making a distinction I'm not familiar with, since usually the terms are used interchangeably.
    – Casey
    Jun 5, 2014 at 19:00
23

Suppose you have a subsystem S that depends on a database connection D. Without dependency injection, there is a relatively tight coupling between S and D, because S needs to know both how to use D and how to create it. The rest of the system, however, can be blissfully unaware of this dependency between S and D.

With dependency injection, the coupling between S and D becomes looser, because you remove from S the knowledge how to create a D. S just needs to know how to use it. The increased overall coupling comes from the fact that other parts of the system now need to know about D and possibly how to create one. The extent of this increase in coupling depends on how the dependency on D gets injected into S:

  • With constructor injection the creator of S needs a dependency on D and possibly the knowledge how to create one.
  • With method-level injection, each caller of a method of S through which a D gets injected needs a dependency on D and possibly the knowledge how to create one.

In either case, the number of classes that depends on D increases and the knowledge how to create a D still needs to be present somewhere in the system. This creates an overall increase of coupling.

2
  • Ok, it makes sense for constructor and setter injection. But if one uses factory or strategy pattern, the creation is moved there, and class only uses the injected object. Or, is that not a dependency injection (only inversion of control)? Jun 4, 2014 at 14:46
  • Even with factory injection, the creator of S needs to supply a factory of D, which means it needs to know that S uses D(or at least some interface of it).
    – Idan Arye
    Jun 4, 2014 at 18:55
7

I strongly disagree that it increases coupling.

Without dependency injection you have tight coupling between a sub system and the concrete implementation of the dependency.

With dependency injection you have decoupled the sub system from the implementation of the dependency.

Making the argument that it increases coupling between the consumer and this sub system is VERY questionable as it implies that the consumer is now tightly coupled to the dependency required by the sub system. All it means is you are writing tightly coupled code that couples your consumer to the dependency. Ideally ALL your code is decoupled.

Constructor Injection:

Dependency resolution is handled by a dependency injection container or a factory. The consumer can get a concrete implementation of the sub system from the dependency injection container or a factory.

The consumer does not need to know what the constructor of the sub system even looks like. There is no coupling to the sub system dependency.

Method Injection:

Same as constructor injection except that now the consumer needs to get a concrete instance of the dependency from the container or factory (or even have it method/constructor injected) and inject it into the method. Again, the consumer is not coupled to a concrete implementation of the dependency.

TL;DR Worst case for dependency injection in a sub system is that the coupling is shifted to consumer code. THERE IS NO OVERALL INCREASE IN COUPLING.

Best case is that all systems are now loosely coupled and dependency injection is controlled through dependency injection containers or factories.

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.