1

Wiki on Inversion of Control:

In IoC, custom-written portions of a computer program receive the flow of control from a generic framework. A software architecture with this design inverts control as compared to traditional procedural programming: in traditional programming, the custom code that expresses the purpose of the program calls into reusable libraries to take care of generic tasks, but with inversion of control, it is the framework that calls into the custom, or task-specific, code.

Spring's ApplicationContext is called IoC container.

When I write in my main() / some method ApplicationContext ctx = new ClasspathXmlApplicationContext(config.xml); MyCls cl = ctx.getBean("name"); I manage control-flow myself. Where is "Inversion of Control" in Wikipedia's terms? I call what I need myself(!), not some (Spring?) framework gives me any callbacks for me to fill with my code.

Spring uses "Inversion of Control" as exact synonym for "Dependency injection" and Wikipedia's article is about something else?

But here is Wiki on "Dependency injection" :

The "injection" refers to the passing of a dependency (a service) into the object (a client) that would use it. Passing the service to the client, rather than allowing a client to build or find the service, is the fundamental requirement of the pattern. Dependency injection is one form of the broader technique of inversion of control. The client delegates the responsibility of providing its dependencies to external code (the injector). the client only needs to know about the intrinsic interfaces of the services because these define how the client may use the services. This separates the responsibilities of use and construction."

Given the above I don't understand how dependency injection can be a form of Inversion of Control, especially in terms of (inversion of) control flow.

This answer (Inversion of Control vs Dependency Injection) is related, but it is not an answer to this question, neither does it directly address control flow question.

P.S. My guess is that I need to look from the "reference frame" of the object itself - then normal control flow is when this code (=this object, its methods) creates new objects (dependencies) itself, and inverted control flow when somebody calls methods of that object passing already created objects-dependencies into it. Then that somebody (just my own code in main()) is like a magical framework and the code inside that object is like code within a call-back method. Just such a mental view of the process.

Code Complete
  • 3,146
  • 1
  • 15
  • 38

1 Answers1

1

There's a lot of confusion about the terminology in this space, but what some people call IoC I call Dependency Injection (DI), exactly for the reason that Inversion of Control is a much broader concept.

When applying DI to a code base, however, you're not supposed to write MyCls cl = ctx.getBean("name"); outside of your Composition Root. This means that most of your code should just use the Constructor Injection pattern, like this:

public class MyCls {
    public MyCls(MyDependency dep) {
        // Assign dep to a class field here...
        // That makes dep available to all method of MyCls.
    }
}

This inverts the control in the sense that MyCls never gets to control MyDependency. This enables the composing code to share instances of MyDependency if that's desired, or create a new instance for each consuming class, if that's safer. Which option is best often depends on implementation details of the concrete class that implements the polymorphic dependency. Following the Liskov Subtitution Principle, the consuming class (MyCls) should have no knowledge of the implementation details of its dependencies, including which lifetime is best. Inverting control over dependencies nicely addresses that sort of issue.

I've tried to provide detailed descriptions, as well as a consistent pattern language, in my book on DI. While I'm a C# developer, I've learned a lot from many books that have examples in Java, so I've tried to perform the reverse manoeuvre and written a book with examples in C# (but on .NET Core so that it compiles on both Linux, Mac, and Windows) that should also be readable for Java developers.

Mark Seemann
  • 225,310
  • 48
  • 427
  • 736