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.