What is addiction injection?

I've heard a lot about Dependency Injection. The question is: how, when and for what to use?

Author: BrTkCa, 2014-06-10

4 answers

Great subject, but that gives an answer book.

I recommend studying Design patterns.

Dependency Injection

Is a design pattern that preaches an external control type, a container, A Class, settings via file, etc., insert a dependency into another class.

Trying to improve: "the Dependency Injection pattern aims to remove unnecessary dependencies between class".

Example

public class PedidosController : Controller
{
    private IPedidoRepository _pedidoRepositorio;
    public PedidosController(IPedidoRepository pedidoRepositorio)
    {
       _pedidoRepositorio = pedidoRepositorio;
    }
        public ActionResult Index()
    {
        var pedidos = _pedidoRepositorio.ObterTodos();
        return View(pedidos);
    }
}

To understand the concept it is also necessary to deepen the knowledge in inversion of control and a bit of the solid principle, after all it is the letter D (depend on an abstraction and not an implementation).

Example of something incorrect, something too coupled.

public class PedidosController : Controller
{
    public ActionResult Index()
    {
        var pedidoRepositorio = new PedidoRepository();
        var pedidos = pedidoRepositorio.ObterTodos();
        return View(pedidos);
    }
}

I recommend the following readings

And the great Martin Fowler:

Summarizing: You place the responsibility for the outside classes on the class you are calling and not on the called Class.

 64
Author: Dorathoto, 2019-08-01 16:47:12

Dependency Injection is a type of control inversion and means that a class is no longer responsible for creating or fetching the objects on which it depends.

This serves to decouple the classes, avoiding direct dependence between them.

The results are:

  • higher reuse rate
  • allows you to add new features without changing existing ones
  • possibility to create mocks in Tests units

Example

I will illustrate a simple case of dependency injection without the need for a container or framework.

Suppose you have a system that processes payments and implements a method as follows:

class Pagamento {

    void efetuarPagamento(String tipo, Integer codigo, Double valor) {
        if ("BOLETO".equals(tipo)) {
            new IntegracaoBoletoBanco().pagarBoleto(codigo, valor);
        } else if ("CARTAO".equals(tipo)) {
            new IntegracaoCartaoBanco().pagarCartao(codigo, valor);
        } else if ("DINHEIRO".equals(tipo)) {
            new IntegracaoContaBanco().pagarDinheiro(codigo, valor);
        }
    }

}

Note that the method directly instantiates several classes. This is very bad because the code is all coupled and it is necessary to perform maintenance whenever some implementation change.

We can refactor this code so that the algorithm becomes more generic. Let's see:

class Pagamento {

    IntegracaoBanco integracaoBanco;

    public Pagamento(IntegracaoBanco integracaoBanco) {
        this.integracaoBanco = integracaoBanco;
    }

    void efetuarPagamento(Integer codigo, Double valor) {
        integracaoBanco.pagar(codigo, valor);
    }

}

Here, IntegracaoBanco is an interface and can receive multiple implementations. Also, class now requires that one of these implementations be passed in the constructor.

Our class no longer has the responsibility to know the implementations of IntegracaoBanco. Who will call it is who must pass the correct instance, injecting this dependency at the time of creation of the class.

This time our code has become much simpler and allows you to create new payment implementations through the interface or extend the classes that are already part of the system without messing with the existing code.

References

See more examples involving inversion of control in my answers here in SOPT:

 48
Author: utluiz, 2017-04-13 12:59:36

This {[4] } answer from SOEN deserves to be translated and left here as a reference:

How to explain addiction injection to a 5 year old boy?

When you go to the fridge to get something for yourself, it can cause problems. You can leave the door open, you can pick up anything that Dad or mom doesn't want you to eat. You can even search for anything we don't have or else find something whose shelf life expire.

What you should do is say what you need, "I need anything to drink at lunch," and then I make sure you get what you need when you go to lunch.

Edit:

A simple example of dependency injection.

No dependency injection:

public void Test()
{
  Logger newLogger = new Logger(...);
  newLogger.Debug("");
}

Assuming the Logger class implements the ILogger interface, you can inject the Logger as follows:

public void Test(ILogger logger)
{
  logger.Debug("");
}

In this way, the responsibility and knowledge of how to instantiate the Logger class stood for the code that call the Test method.

 34
Author: Omni, 2020-06-11 14:45:34

Second article, which I had the audacity to translate, written by Steve Smith and Scott Addie on 10/02/2017 for Microsoft...

Dependency Injection is a technique to rid or remove coupling between objects and their collaborators, or dependents. Instead of instantiating collaborator objects directly, or using static references; these collaborators are provided to the dependent class in a particular way. Generally, these classes will declare their dependencies through its constructors, thus following the principle of explicit dependencies. This way of performing a dependency injection is known as"constructor injection".

When classes are developed, taking dependency injection into account, they are less coupled, this is because there is no code directly referencing them in their dependents. This form follows the "Dependency Inversion Principle", which preaches the following: "high-level modules should not depend on low-level modules; both must depend on abstractions." Instead of referencing a specific implementation, dependent classes must request abstractions (usually Interfaces), which are provided to them at the time of class creation. Extracting dependents into interfaces and providing implementations of these interfaces as parameters are also an example of the strategy development pattern.

When a system is developed to use Dependency Injection with many dependency requests via constructor (or properties), it is useful to have a dedicated class to create these classes along with their associated dependencies. These classes are referenced as repositories, or more specifically, "inversion of control (IoC)" repositories or dependency injection (DI) repositories. A repository is essentially a factory that is responsible for providing instances of types that are requested from them. If a specific type has declared that it has dependencies, and the repository has been configured to provide the type dependencies, it will create the dependencies as part of the instance creation request. In this way, a complex dependency chain can be provided to class without any fixed code being inserted into its constructor. In addition to creating objects with their dependencies, repositories often manage the object lifecycle in the application.

Ref: https://docs.microsoft.com/pt-br/aspnet/core/fundamentals/dependency-injection (accessed on 09/21/2017).

 8
Author: Rafael, 2017-09-21 13:50:16