55

I've been reading up more on the Inversion of Control principle and Dependency Injection as an implementation of it and am pretty sure I understand it.

It seems to be basically saying 'don't declare your class members' instantiations within the class'. Rather that the instantiations should be passed in and assigned through the constructor; 'injected' into the class from an outside source.

If it's this simple, which it seems to be, why do we need frameworks like spring or guice that implement this with annotations? Am I missing something fundamental here? I'm really struggling to understand what the use of Dependency Injection frameworks are.

Edit: About the possible duplicate, I believe my question is more unique as it is asking about DI frameworks in general, not just Spring. Spring is not just a DI framework, so there are many reasons that someone would want to use Spring that aren't related to DI.

timsworth
  • 661
  • 1
  • 5
  • 6
  • Possible duplicate of [What does the Spring framework do? Should I use it? Why or why not?](http://programmers.stackexchange.com/questions/92393/what-does-the-spring-framework-do-should-i-use-it-why-or-why-not) – gnat Oct 17 '15 at 19:28
  • 15
    They are useful for shifting errors into runtime instead of compile time. – Den Oct 19 '15 at 13:05
  • 3
    @den Why would we want to do that? That seems to violate fail fast – THIS USER NEEDS HELP Mar 24 '18 at 21:44
  • To quote from [Guice](https://github.com/google/guice/wiki/Motivation#dependency-injection), without a DI framework, whenever you instantiate an object, you'll need to recursively instantiate all its dependencies. A DI framework (at least for Guice), does this recursive instantiation for you automatically when you instantiate the top level object. – Rufus Nov 26 '21 at 12:51

4 Answers4

36

We don't need the frameworks. It is entirely possible to implement dependency injection manually, even for a relatively large project.

On the other hand, using a framework makes it easier, particularly one based on annotations or automatic detection of dependencies, as it makes the process simpler: if I decide that I need a new dependency in a class, all I have to do is add it to the constructor (or declare a setter) and the object is injected - I don't need to change any instantiation code.

Also, frameworks often contain other useful functionality. Spring, for example, contains a useful framework for aspect oriented programing, including declarative transaction demarcation (which is extremely handy) and a variety of adapter implementations that make many 3rd party libraries easier to integrate.

Jules
  • 17,614
  • 2
  • 33
  • 63
  • 13
    Hit the nail on the head. We ***don't*** need them. They just make life easier for large projects. Honestly, I find that frameworks are more hassle than they're worth for smaller projects. I'd encourage OP to not confuse Dependency Injection with the frameworks that support it. – RubberDuck Oct 17 '15 at 21:29
  • 1
    well said. And why reinvent the wheel when someone else has made one that's nice and round already? – jwenting Oct 17 '15 at 22:14
  • Exactly that. Except *I don't need to change any instantiation code* - of course, *there is no instantiation code* ;-) – Mathieu Guindon Oct 18 '15 at 02:04
  • It just looks like your DI libraries suck. Good ones can guess the class to instantiate using reflection. – Florian Margaine Oct 18 '15 at 09:03
  • 3
    anyone using reflection for runtime processing is doing it wrong. Reflection is one of those technologies that, just because you can do something doesn't mean you should. – gbjbaanb Oct 19 '15 at 14:10
18
  1. Why do we need DI (Dependency Injection) at all?

    The DI mechanism separates object production from object consumption. The dependecies an object needs are delivered transparently from the outside. The advantage of the mechanism is clear: You could anytime swap out dependencies, e.g. usìng a Null Object for testing purposes.

  2. How is it done?

    There are several ways to achieve the goal:

    • Injecting dependencies via constructor injection
    • Injection via getter/setter
    • Interface Injection
  3. Do we need DI frameworks?

    No. Not at all. You could simply pass all instances to other objects manually. If you have a small application, there is no need for a spring container.

    But on the other hand, frameworks give you a helping hand, managing objects:

    • They help you wiring up complex object relationships. You have to write no boilerplate code, to generate instances and pass them to the appropriate objects

    • They help you control when an object is created: you could create instances during application bootstrapping, but in some cases a lazy creation - only when needed - is better

    • They help you control how many instances are created: one per application lifetime or one per request (in case you are doing web-programming)

If you project has an appropriate size - if you feel the need to write less boilerplate code - it totally makes sense using a (DI-) framework. There are more pros than cons.

Tulains Córdova
  • 39,201
  • 12
  • 97
  • 154
Thomas Junk
  • 9,405
  • 2
  • 22
  • 45
5

With spring, it is mostly a matter of convenience.

If you have class TopLevel which is constructs class MiddleLevel which constructs class LowLevel, and you realize you need a new constructor parameter on LowLevel, you have to also add it to TopLevel, and to MiddleLevel, simply so that when it is time for MiddleLevel to construct a LowLevel the value will be available so that it can be passed to its constructor. With spring, you just add an annotation.

Also, with spring, it is possible to define the dependencies in an external configuration file instead of xml, and this supposedly gives you the ability to generate a new system with an entirely different wiring "without changing any code". (IMHO this is completely misdirected, because altering xml is not that much different from altering code, and actually, code usually has far better error checking and type checking than xml does.)

Another thing is that many people are afraid of constructors; they don't understand them, they don't like them, they'd rather not use them.

Mike Nakis
  • 32,003
  • 7
  • 76
  • 111
  • 4
    Mostly agree, especially with the XML remark. IMHO, being afraid of constructors is probably a bad reason to use a DI framework. – Robert Harvey Oct 17 '15 at 20:04
  • 4
    IMHO, being afraid of constructors is a good reason to stay away from programming. C-:= – Mike Nakis Oct 17 '15 at 20:07
  • 6
    But how is this an advantage over a factory (static or otherwise)? (Which has the advantage of being an option you can use as appropriate whereas spring seems to be an all or nothing afair) – Richard Tingle Oct 17 '15 at 20:23
  • @RichardTingle Spring may represent an advantage mostly due to all the other things that it does besides DI, because obviously, you can achieve DI in many other ways, static factories being one. (One of the least cool, but still.) But what the question asks is whether it is necessary to use spring in order to achieve DI, and that's what I have been trying to answer: basically, it is not necessary, just a convenience. – Mike Nakis Oct 17 '15 at 20:30
  • This is an example of what DI is not. ´TopLevel` should not create `MiddleLevel`, but should receive it when constructing `TopLevel` as an argument to the constructor. Likewise `MiddleLevel` should receive a `LowLevel` in its constructor. – Clearer Nov 26 '18 at 15:09
2

A few years ago I wrote a program to monitor web pages, web portlets, even certain database tables, at a company I used to work for. I wanted it to be flexible enough that the user could specify which monitors would run and with which parameters (urls, logins, success criteria, etc.). So I wrote it to read from an XML file and use Java reflection to instantiate the specified classes and use setter methods to set the specified parameters.

Later I found that out Spring will do the same thing for you, and a whole lot more.

So in my case I found that

  1. Using a dependency injection framework helps make the program flexible and makes it easier to specify how it will operate (within well defined parameters of course).

  2. Using a third party DI framework keeps you from having to reinvent the wheel.

Paul J Abernathy
  • 155
  • 1
  • 1
  • 5
  • 5
    Could you explain more about why defining which concrete class to use is better inside an xml rather than within a java file. That's the thing I've never understood. – Richard Tingle Oct 20 '15 at 06:10
  • 2
    It's no magic bullet, but one advantage to using config files is that, at least in theory, they are easier to edit than code. Plus, they can be changed by a user who is running your program but does not have access to your source code. In the example I gave of my crude dependency injection program, I would sometimes change the XML config file so I could change how the program ran even though I was the one who wrote it. If you don't need the external configurability, it can be easier to do it with code. I had another job where we did all the DI in the code and that worked well. – Paul J Abernathy Oct 20 '15 at 15:55