What are the benefits of dependency injection containers?

I understand benefits of dependency injection itself. Let's take Spring for instance. I also understand benefits of other Spring featureslike AOP, helpers of different kinds, etc. I'm just wondering, what are the benefits of XML configuration such as:

<bean id="Mary" class="foo.bar.Female">
  <property name="age" value="23"/>
</bean>
<bean id="John" class="foo.bar.Male">
  <property name="girlfriend" ref="Mary"/>
</bean>

compared to plain old java code such as:

Female mary = new Female();
mary.setAge(23);
Male john = new Male();
john.setGirlfriend(mary);

which is easier debugged, compile time checked and can be understood by anyone who knows only java. So what is the main purpose of a dependency injection framework? (or a piece of code that shows its benefits.)


UPDATE:
In case of

IService myService;// ...
public void doSomething() {  
  myService.fetchData();
}

How can IoC framework guess which implementation of myService I want to be injected if there is more than one? If there is only one implementation of given interface, and I let IoC container automatically decide to use it, it will be broken after a second implementation appears. And if there is intentionally only one possible implementation of an interface then you do not need to inject it.

It would be really interesting to see small piece of configuration for IoC which shows it's benefits. I've been using Spring for a while and I can not provide such example. And I can show single lines which demonstrate benefits of hibernate, dwr, and other frameworks which I use.


UPDATE 2:
I realize that IoC configuration can be changed without recompiling. Is it really such a good idea? I can understand when someone wants to change DB credentials without recompiling - he may be not developer. In your practice, how often someone else other than developer changes IoC configuration? I think that for developers there is no effort to recompile that particular class instead of changing configuration. And for non-developer you would probably want to make his life easier and provide some simpler configuration file.


UPDATE 3:

External configuration of mapping between interfaces and their concrete implementations

What is so good in making it extenal? You don't make all your code external, while you definitely can - just place it in ClassName.java.txt file, read and compile manually on the fly - wow, you avoided recompiling. Why should compiling be avoided?!

You save coding time because you provide mappings declaratively, not in a procedural code

I understand that sometimes declarative approach saves time. For example, I declare only once a mapping between a bean property and a DB column and hibernate uses this mapping while loading, saving, building SQL based on HSQL, etc. This is where the declarative approach works. In case of Spring (in my example), declaration had more lines and had the same expressiveness as corresponding code. If there is an example when such declaration is shorter than code - I would like to see it.

Inversion of Control principle allows for easy unit testing because you can replace real implementations with fake ones (like replacing SQL database with an in-memory one)

I do understand inversion of control benefits (I prefer to call the design pattern discussed here as Dependency Injection, because IoC is more general - there are many kinds of control, and we are inverting only one of them - control of initialization). I was asking why someone ever needs something other than a programming language for it. I definitely can replace real implementations with fake ones using code. And this code will express same thing as configuration - it will just initialize fields with fake values.

mary = new FakeFemale();

I do understand benefits of DI. I do not understand what benefits are added by external XML configuration compared to configuring code that does the same. I do not think that compiling should be avoided - I compile every day and I'm still alive. I think configuration of DI is bad example of declarative approach. Declaration can be useful if is declared once AND is used many times in different ways - like hibernate cfg, where mapping between bean property and DB column is used for saving, loading, building search queries, etc. Spring DI configuration can be easily translated to configuring code, like in the beginning of this question, can it not? And it is used only for bean initialization, isn't it? Which means a declarative approach does not add anything here, does it?

When I declare hibernate mapping, I just give hibernate some information, and it works based on it - I do not tell it what to do. In case of spring, my declaration tells spring exactly wht to do - so why declare it, why not just do it?


LAST UPDATE:
Guys, a lot of answers are telling me about dependency injection, which I KNOW IS GOOD. The question is about purpose of DI configuration instead of initializing code - I tend to think that initializing code is shorter and clearer. The only answer I got so far to my question, is that it avoids recompiling, when the configuration changes. I guess I should post another question, because it is a big secret for me, why compiling should be avoided in this case.

104
2022-07-19 22:01:51
Source Share
Answers: 9

Ease of combining partial configurations into a final complete configuration.

For example, in web applications, the model, view and controllers are typically specified in separate configuration files. Use the declarative approach, you can load, for example:

  UI-context.xml
  Model-context.xml
  Controller-context.xml

Or load with a different UI and a few extra controllers:

  AlternateUI-context.xml
  Model-context.xml
  Controller-context.xml
  ControllerAdditions-context.xml

To do the same in code requires an infrastructure for combining partial configurations. Not impossible to do in code, but certainly easier to do using an IoC framework.

1
2022-07-24 01:02:36
Source

In the .NET world, most of IoC frameworks provide both XML and Code configuration.

StructureMap and Ninject, for example, use fluent interfaces to configure containers. You are no longer constrained to use XML configuration files. Spring, which also exists in .NET, heavily relies on XML files since it is his historical main configuration interface, but it is still possible to configure containers programmatically.

1
2022-07-20 12:50:43
Source

You do not require to recompile your code each time you transform something in arrangement. It will certainly streamline program release and also upkeep. As an example you can exchange one part with an additional with simply 1 adjustment in config documents.

2
2022-07-20 12:50:26
Source

This is a little a crammed inquiry, yet I often tend to concur that massive quantities of xml arrangement does not actually total up to much advantage. I like my applications to be as light on dependences as feasible, consisting of the substantial structures.

They streamline the code a great deal of the moments, yet they additionally have an expenses in intricacy that makes locating troubles instead hard (I have actually seen such troubles first hand, and also straight Java I would certainly be a whole lot extra comfy managing).

I presume it relies on design a little bit, and also what you fit with do you like to fly your very own remedy and also have the advantage of recognizing it from top to bottom, or rely on existing remedies that might confirm hard when the arrangement isn't ideal? It is all a tradeoff.

Nonetheless, XML arrangement is a little a pet dog peeve of mine I attempt to prevent it in all prices.

7
2022-07-20 12:50:23
Source

Spring additionally has a buildings loader. We utilize this method to set variables that are dependant on the setting (as an example growth, screening, approval, manufacturing, ). This can be as an example the line up to pay attention to.

If there is no reason that the building would certainly transform, there is additionally no factor to configure it this way.

0
2022-07-20 12:50:19
Source

Your case is very simple and therefore doesn't need an IoC (Inversion of Control) container like Spring. On the other hand, when you "program to interfaces, not implementations" (which is a good practice in OOP), you can have code like this:

IService myService;
// ...
public void doSomething() {
  myService.fetchData();
}

(note that the type of myService is IService -- an interface, not a concrete implementation). Now it can be handy to let your IoC container automatically provide the correct concrete instance of IService during initialization - when you have many interfaces and many implementations, it can be cumbersome to do that by hand. Main benefits of an IoC container (dependency injection framework) are:

  • External configuration of mapping between interfaces and their concrete implementations
  • IoC container handles some tricky issues like resolving complicated dependency graphs, managing component's lifetime etc.
  • You save coding time because you provide mappings declaratively, not in a procedural code
  • Inversion of Control principle allows for easy unit testing because you can replace real implementations with fake ones (like replacing SQL database with an in-memory one)
0
2022-07-20 12:49:46
Source

You can port in a new execution for partner. So new lady can be infused without recompiling your code.

<bean id="jane" class="foo.bar.HotFemale">
  <property name="age" value="19"/>
</bean>
<bean id="mary" class="foo.bar.Female">
  <property name="age" value="23"/>
</bean>
<bean id="john" class="foo.bar.Male">
  <property name="girlfriend" ref="jane"/>
</bean>

(The over thinks Female and also HotFemale implement the very same GirlfFriend user interface)

2
2022-07-20 12:48:31
Source

One of the most appealing reasons is the "Hollywood principle": don't call us, we'll call you. A component is not required to do the lookups to other components and services itself; instead they are provided to it automatically. In Java, this means that it is no longer necessary to do JNDI lookups inside the component.

It is also lots easier to unit test a component in isolation: instead of giving it an actual implementation of the components it needs, you simply use (possibly auto generated) mocks.

0
2022-07-20 12:41:02
Source

Dependency injection is a coding style that has its roots in the observation that object delegation is usually a more useful design pattern than object inheritance (i.e., the object has-a relationship is more useful than the object is-a relationship). One other ingredient is necessary however for DI to work, that of creating object interfaces. Combining these two powerful design patterns software engineers quickly realized that they could create flexible loosely coupled code and thus the concept of Dependency Injection was born. However it wasn't until object reflection became available in certain high level languages that DI really took off. The reflection component is core to most of today's DI systems today because the really cool aspects of DI require the ability to programmatically select objects and configure and inject them into other objects using a system external and independent to the objects themselves.

A language must provide good support for both normal Object Oriented programming techniques as well as support for object interfaces and object reflection (for example Java and C#). While you can build programs using DI patterns in C++ systems its lack of reflection support within the language proper prevents it from supporting application servers and other DI platforms and hence limits the expressiveness of the DI patterns.

Strengths of a system built using DI patterns:

  1. DI code is much easier to reuse as the 'depended' functionality is extrapolated into well defined interfaces, allowing separate objects whose configuration is handled by a suitable application platform to be plugged into other objects at will.
  2. DI code is much easier to test. The functionality expressed by the object can be tested in a black box by building 'mock' objects implementing the interfaces expected by your application logic.
  3. DI code is more flexible. It is innately loosely coupled code -- to an extreme. This allows the programmer to pick and choose how objects are connected based exclusively on their required interfaces on one end and their expressed interfaces on the other.
  4. External (Xml) configuration of DI objects means that others can customize your code in unforeseen directions.
  5. External configuration is also a separation of concern pattern in that all problems of object initialization and object interdependency management can be handled by the application server.
  6. Note that external configuration is not required to use the DI pattern, for simple interconnections a small builder object is often adequate. There is a tradeoff in flexibility between the two. A builder object is not as flexible an option as an externally visible configuration file. The developer of the DI system must weigh the advantages of flexibility over convenience, taking care that small scale, fine grain control over object construction as expressed in a configuration file may increase confusion and maintenance costs down the line.

Definitely DI code seems more cumbersome, the disadvantages of having all of those XML files that configure objects to be injected into other objects appears difficult. This is, however, the point of DI systems. Your ability to mix and match code objects as a series of configuration settings allows you to build complex systems using 3rd party code with minimal coding on your part.

The example provided in the question merely touches on the surface of the expressive power that a properly factored DI object library can provide. With some practice and a lot of self discipline most DI practitioners find that they can build systems that have 100% test coverage of application code. This one point alone is extraordinary. This is not 100% test coverage of a small application of a few hundred lines of code, but 100% test coverage of applications comprising hundreds of thousands of lines of code. I am at a loss of being able to describe any other design pattern that provides this level of testability.

You are correct in that an application of a mere 10s of lines of code is easier to understand than several objects plus a series of XML configuration files. However as with most powerful design patterns, the gains are found as you continue to add new features to the system.

In short, large scale DI based applications are both easier to debug and easier to understand. While the Xml configuration is not 'compile time checked' all application services that this author is aware of will provide the developer with error messages if they attempt to inject an object having an incompatible interface into another object. And most provide a 'check' feature that covers all known objects configurations. This is easily and quickly done by checking that the to-be-injected object A implements the interface required by object B for all configured object injections.

17
2022-07-19 22:57:14
Source