Diferença entre Injeção de Dependência (DI) e Inversão de Controle (COI)

117

Eu tenho visto muitas referências de Injeção de Dependência (DI) e Inversão de Controle (COI), mas realmente não sei se existe uma diferença entre elas ou não.

Gostaria de começar a usar um ou os dois, mas estou um pouco confuso sobre como eles são diferentes.

mosquito
fonte
Inversão de controle geralmente se refere aos "contêineres", enquanto a injeção de dependência se refere ao padrão real. Mas eles andam de mãos dadas. Eu recomendaria a leitura do artigo de Martin Fowler para entender o assunto.
Ben Hoffstein
Injeção de dependência é algo que você faz, o que leva a uma estrutura de comando chamada Inversão de controle. Eles estão inerentemente vinculados.
2
DI é uma forma de IoC, eu dei uma explicação muito detalhada de DI e IoC em esta resposta
2
Eu diria que o DI é um caso especial do COI. O controle tradicional vai de módulo-> módulo de solicitação ao gerenciador de módulos, no DI é invertido para gerente de módulo-> obtém dependências solicitadas do módulo.
Rafał Dowgird 26/09/08
Portanto, em outras palavras, basicamente IoC é uma implementação do uso de DI. Estou entendendo corretamente?
dance2die

Respostas:

53

Definições

A inversão do controle é um paradigma de design com o objetivo de reduzir o reconhecimento de implementações concretas a partir do código da estrutura do aplicativo e dar mais controle aos componentes específicos do domínio do seu aplicativo. Em um sistema tradicional de cima para baixo, o fluxo lógico do aplicativo e do reconhecimento de dependência flui dos componentes principais, os projetados primeiro, e os projetados por último. Como tal, a inversão de controle é uma reversão quase literal da conscientização de controle e dependência em um aplicativo.

Injeção de dependência é um padrão usado para criar instâncias de classes nas quais outras classes dependem sem saber em tempo de compilação qual implementação será usada para fornecer essa funcionalidade.

Trabalhando juntos

A inversão do controle pode utilizar a injeção de dependência, pois é necessário um mecanismo para criar os componentes que fornecem a funcionalidade específica. Outras opções existem e são usadas, por exemplo, ativadores, métodos de fábrica, etc., mas as estruturas não precisam fazer referência a essas classes de utilitário quando as classes de estrutura podem aceitar as dependências de que precisam.

Exemplos

Um exemplo desses conceitos em ação é a estrutura de plug-in no Reflector . Os plug-ins têm muito controle do sistema, embora o aplicativo não soubesse nada sobre os plug-ins no momento da compilação. Um único método é chamado em cada um desses plug-ins, Inicialize se a memória servir, que passa o controle para o plug-in. A estrutura não sabe o que eles farão, apenas permite que eles façam. O controle foi retirado da aplicação principal e entregue ao componente que está executando o trabalho específico; inversão de controle.

A estrutura do aplicativo permite acesso a sua funcionalidade por meio de uma variedade de provedores de serviços. Um plug-in recebe referências aos provedores de serviços quando ele é criado. Essas dependências permitem que o plug-in inclua seus próprios itens de menu, altere como os arquivos são exibidos, exiba suas próprias informações nos painéis apropriados, etc. Como as dependências são transmitidas pela interface, as implementações podem mudar e as alterações não quebram o código enquanto o contrato permanecer intacto.

Na época, um método de fábrica era usado para criar os plug-ins usando informações de configuração, reflexão e o objeto Activator (pelo menos no .NET). Hoje, existem ferramentas, MEF para um, que permitem uma gama mais ampla de opções ao injetar dependências, incluindo a capacidade de uma estrutura de aplicativo aceitar uma lista de plug-ins como uma dependência.

Sumário

Embora esses conceitos possam ser usados ​​e oferecer benefícios de forma independente, juntos eles permitem a criação de códigos muito mais flexíveis, reutilizáveis ​​e testáveis. Como tal, são conceitos importantes no design de soluções orientadas a objetos.

Mandril
fonte
3
Não, a IoC é um conceito mais antigo e é independente da DI (que não depende da IoC). Por exemplo, considere a estrutura Struts (Java): ela depende muito da IoC, mas não usa DI.
Rogério
1
@ Rogério - Você enfatiza que os dois conceitos não se exigem. Atualizei minha resposta para esclarecer isso e, em seguida, descrevi rapidamente como algumas estruturas as utilizam em conjunto para permitir um código mais frouxamente acoplado.
Chuck
A aplicação mais simples da IoC provavelmente seria o ActionListener. Em vez de manipular processualmente o código, o código de manipulação de eventos é delegado ao código personalizado. Invertendo o controle.
Mike
0

Bom artigo para entender o COI e o DI http://martinfowler.com/articles/injection.html

COI (Inversão de Controle)

COI significa

  1. codificação para interface (um componente deve depender da interface de outro componente e não de impl), e por exemplo

    interface iComp_2 {...}
    
    class Comp_1 {
        iComp_2 c2 = ….;
    }
    
  2. remover o código específico de implementação do componente, por exemplo

    Comp_1 {
        iComp_2 c2 = getComp_2_Impl(); // not new Comp_2_Impl();
    }
    

O COI pode ser alcançado por um dos seguintes procedimentos:

1. DI (Injeção de Dependência)

3 types of DI

1.1 Constructor Injection

1.2 Setter Injection

1.3 Interface Injection

2. Localizador de Serviço

Recipiente DI (injeção de dependência)

Determinação de tempo de execução do implemento e não tempo de compilação: determina em tempo de execução qual implementação concreta de uma interface a ser usada com base em algum arquivo de configuração (portanto, no tempo de compilação, não sabemos qual impl será usado e, portanto, aumenta a configurabilidade do aplicativo) . É uma implementação em que a relação concreta entre os diferentes módulos é decidida em "tempo de execução".

Instanciação do impl após a injeção de dependência: após determinar o impl, ele o instancia criando primeiro todas as suas dependências (especificadas no arquivo de configuração) e, em seguida, injetando essas dependências no impl

Gerenciamento do ciclo de vida da instância: os contêineres DI normalmente mantêm apenas uma referência aos objetos para os quais ele precisa gerenciar os ciclos de vida ou que são reutilizados para futuras injeções, como singletons ou flyweights. Quando configurado para criar novas instâncias de alguns componentes para cada chamada ao contêiner, o contêiner geralmente esquece apenas o objeto criado. Caso contrário, o coletor de lixo teria dificuldade em coletar todos esses objetos quando não fosse mais usado.

Yatendra Goel
fonte
6
Você realmente leu o artigo "injeção"? COI não significa o que esta resposta diz, de maneira alguma.
Rogério
-3

Eu diria que "Inversão de controle" é uma maneira de projetar um sistema em que todos os módulos são pensados ​​em entidades abstratas.

E "Injeção de Dependência" é uma implementação em que a relação concreta entre diferentes módulos é decidida em "tempo de execução".

mB.
fonte
-4

Inversão de controle é um conceito geral, em linguagens funcionais geralmente é feito usando continuações. Isso permite que você escreva uma API em que ambos os lados sejam 'chamadores' e nenhum seja 'chamado'. Em outros ambientes mais estáticos, você não tem essa facilidade, portanto, precisa desse hack para inserir dicas no fluxo de controle.

Javier
fonte