Monday, June 01, 2009

Depency Injection/Inversion of Control - are they the same?

On the weekend I spoke to a friend and we were talking about the SOLID principles. We talked at lengh about Inversion of Control/Dependency Injection and how they are not the same thing. Trumpi was saying that you use dependency injection to achieve inversion of control, and that made sense to me. Then I consulted with another colleague about it and this colleague pointed that in order to achieve inversion of control then you will necessarily be doing some form of dependency injection. You will need to "inject" the dependency because the component requiring the dependency will only depend on an abstraction.

So in effect, they are the same thing. The different phrases describe the mechanism from different point of views, the one describes the behaviour (dependency injection), the other the structure (Inversion of Control).

What I also discovered as I opened the book, Agile Software Development, which I think, first explained the SOLID principles, presents the 'I' of SOLID as "Dependency Inversion", i.e. a combination of inversion of control and dependency injection. Which to my mind, is a better moniker as it describes the mechanism more accurately.

9 comments:

Dusan said...

In fact inversion of control is more general term. Inversion of control means that you have given up creation of new instances by yourself("new" keyword). This can be achieved by different ways. One is dependency injection in which the dependencies are set to your instance by container(instance is not aware of container)...
Other one is "dependecy pull" this means that you are actively aware of a container and pulling the instances out of it(for example in java jndi lookup, or this kind of thing.



(Sorry for my not very good english)

Unknown said...

@Dusan "This can be achieved by different ways." Like how?

Giorgio said...

A service locator is another way of doing inversion of control, but I do not recommend it.

Michael Wiles said...

The thing is, as soon as your component uses X, e.g. Service locator or jndi to acquire its dependencies, though you have inverted the control to some extent, the class has retained some control and I'd prefer the class to not have any control.

To truly invert the control, i.e. for the class to have no knowledge about its dependencies (details), you necessarily have to inject them.

I'm not sure if this is part of the inversion of control pattern but I'd prefer a system where the class is _not_ responsible for acquiring its dependencies at all. That is true inversion of control.

Using service locator and or jndi means the class is responsible for acquiring its dependencies. Thus if you wish to change how those details are acquired you will have to change the class - effectively breaking the inversion of control.

Frank Silbermann said...

The goal is the segregation of arbitrary infrastructural choices (such as RDBMS products, loggers, and communications middleware) from the business logic, so that these can be tested and maintained independently.

Comparing programs which achieve this segregation with those that do not, it appears that there has been an inversion of control. That is, rather than embedding arbitrary infrastructural details within the routines that implement the business logic, a new top layer (1) builds the necessary infrastructure and (2) provides the business logic routines with access to this infrastructure. Hence, the (admittedly vague) expression _Inversion of Control_.

Because business logic execution depends upon access to the computational infrastructure, step (2) above is called Dependency Injection.

The expression "Dependency Injection" is specific as to the goal, but does not refer to the entire process -- as you cannot inject a dependency unless you first build it out. But it covers the most important part.

The expression "Inversion of Control" covers the entire process, but the words are so general that it theoretically could refer to any kind of control inversion that might exist for whatever reason.

Therefore, Dependency Injection is the better terminology.

Anonymous said...
This comment has been removed by a blog administrator.
Trumpi said...

Here is another point that proves that Dependency Inversion and Dependency Injection are not the same: You can inject all your dependencies, but still not achieve dependency inversion. How? By not declaring your dependencies abstract enough.

So instead of declaring public MyConstructor(AbstractDependency d), you declare MyConstructor(ConcreteDependency d). You are using dependency injection, but you are not achieving dependency inversion.

Trumpi said...

This is probably a typo, but the Dependency Inversion Principle is the 'D' in SOLID and not the 'I'.

The 'I' would be the Interface Segregation Principle.

Michael Wiles said...

Creating the dependency outside the component and then providing it to the component is not a sufficient condition for achieving dependency injection. The component must necessarily also not depend on the details, otherwise the dependency cannot be injected, it has been "hard coded".

btw, thanks for pointing out the error wrt which letter of SOLID is relevant.

How important is the programming language?

  Python, typescript, java, kotlin, C#, .net… Which is your technology of choice? Which one are you currently working in and which do you wa...