What is addiction injection?

Asked

Viewed 25,411 times

71

I have heard a lot about addiction injection. The question is: How, when and what to use?

4 answers

67


Great subject, but this gives a reply book.

I recommend the study on Design Patterns.

Dependency injection

Is a Design Pattern which preaches a kind of external control, a container, a class, file settings, etc., insert a dependency into another class.

Trying to improve: "The dependency injection pattern aims to remove unnecessary dependencies between classes".

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 very attached.

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:

In short: You place the responsibility of external classes in the class you are calling and not in the class called.

  • 1

    Have a great book and cheap and in English: Refactoring - Perfecting the Existing Code Project

  • 1

    Cool for the tip. I will change jobs and I will need a lot of concepts. This is a Pattern not foreseen by the Gof, right? I need to study project patterns and not only understand, but mainly implement them. Thanks for the tip.

  • 1

    Design Pattern would be Design Patterns. and there are several Gof, GRASP, etc., although each one has its standards I believe that all walk for the same purpose, I think that the concept SOLID understood in the integrates helps in all principles.

  • The link passed above, from Macoratti, which I’m reading right now, is giving me a legal sense of the subject. Of course much more is needed, but it is already a beginning, a compass that points north in this matter.

  • Guys, do you have any idea what was built here? I’m sure this post, not because it was mine, but it’s a real encyclopedia on the subject. Very rich in information on the subject and details.

  • 1

    Taking advantage of utLuiz, I see that your answer is more formal, without an opinion as if you were a journalist, this is the correct answer right? should I remove things like "great question?" "the tip is:" ?

  • Dependency injection is not the same thing as dependency inversion.

Show 2 more comments

49

Injection of Dependencies is a type of Control Inversion and means that a class is no longer responsible for create or seek the objects on which it depends.

This serves to decouple classes, avoiding direct dependency between them.

The results are:

  • Higher rate of reuse
  • Allows adding new features without changing existing ones
  • Possibility of creating mocks in unit tests

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 instantiation method directly involves several classes. This is very bad because the code gets all coupled and it is necessary to perform maintenance whenever any implementation changes.

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 one of these implementations to be passed in the constructor.

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

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

References

See more examples involving Control Inversion in my answers here at SOPT:

  • doubt: I can say that injection of dependency is only to transfer the responsibility of the class to who is instantiating it? In your example where would be the method that defined which form of payment?

  • 1

    @Marconi Basically yes. More generally, it consists in externalizing the responsibility of instantiation. It can be for the caller or a central manager, such as a dependency injection framework. The idea is that the caller calls the payment knows the type and can pass the correct instance. Note that this is a very simplistic example and obviously a real class will have more logic to justify the existence of a new class.

  • @utluiz, very good your explanation is simple and objective.

35

This SOEN response deserves to be translated and left here as reference:

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

When you go to the refrigerator (fridge, in pt_BR) to get something for yourself, it can cause problems. You can leave the door open, you can take anything Mom or Dad don’t want you to eat. You can even look for something we don’t have or find something whose expiration date has expired.

What you should do is say what you need, "I need something to drink for lunch," and then I’ll make sure you get what you need.

Edit:

A simple example of addiction injection.

No injection of addiction:

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 remained for the code that calls the Test method.

  • 1

    show.. but the best translation for en would be Refrigerator and not Refrigerator...rs But the answer is good.. rs

  • 3

    @Dorathoto PT-PT does not recognize the word refrigerator eheh

8

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 free or remove the coupling between objects and their collaborators, or dependents. Instead of instantiating contributor objects directly, or using static references; these contributors are provided to the dependent class in a particular way. Generally, these classes will declare their dependencies through their constructors, thus following the Explicit Dependency Principle. This way of performing a dependency injection is known as "Injection by Builder".

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

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 referred to as repositories, or more specifically, "Inversion 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. If a specific type has stated 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 usually manage the life cycle of the object in the application.

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

Browser other questions tagged

You are not signed in. Login or sign up in order to post.