Toda vez que alguém me chega e me pede para definir a Injeção de Dependência de uma maneira conceitual e explicar os prós e contras reais do uso de DI no design de software. Confesso que tenho algumas dificuldades para explicar os conceitos de DI. Toda vez que preciso contar a eles a história sobre o princípio de responsabilidade única, composição sobre herança etc.
Alguém pode me ajudar a explicar a melhor maneira de descrever o DI para desenvolvedores?
design
design-patterns
software
Tiago Sampaio
fonte
fonte
Respostas:
Injeção de Dependência é um nome horrível (IMO) 1 para um conceito bastante direto. Aqui está um exemplo:
DbContext
). Esse recurso interno é chamado de dependênciaDbContext
) do método e torna responsabilidade do chamador fornecer esse recurso (como parâmetro do método ou por instanciação da classe)[1] : Eu sou de nível inferior e levei meses para me sentar e aprender a injeção de dependência, porque o nome indica que seria algo muito mais complicado, como DLL Injection . O fato de o Visual Studio (e nós desenvolvedores em geral) se referir às bibliotecas .NET (DLLs ou assemblies ) dos quais um projeto depende, pois as dependências não ajuda em nada. Existe até o Walker de Dependências (depends.exe) .
[Editar] Imaginei que algum código de demonstração seria útil para alguns, então aqui está um (em C #).
Sem injeção de dependência:
Seu consumidor faria algo como:
A mesma classe implementada com padrão de injeção de dependência seria assim:
Agora é responsabilidade do chamador instanciar
DbContext
e passar (errar, injetar ) para sua classe:fonte
Os conceitos abstratos são frequentemente melhor explicados usando uma analogia do mundo real. Esta é a minha analogia básica:
Não é perfeito, mas destaca o principal recurso: dar controle ao consumidor . O benefício mútuo inerente é que você não precisa mais adquirir suas próprias dependências, e seu consumidor é impedido na escolha da dependência.
fonte
Resposta simples para isso:
O .Net Core é um bom exemplo que você pode dar, porque essa estrutura usa muita injeção de dependência. Geralmente, os serviços que você deseja injetar estão localizados no
startup.cs
arquivo.Certamente, o aluno deve estar ciente de alguns conceitos como polimorfismo, interfaces e princípios de design de OOP.
fonte
Há muito fluff e bunkum em torno do que é, em essência, um conceito simples.
Também é muito fácil se atolar com " qual estrutura devo usar " quando você pode fazer isso simplesmente no código.
Esta é a definição que eu pessoalmente uso:
Alguns exemplos podem ser onde Y é um sistema de arquivos ou uma conexão com o banco de dados.
Estruturas como moq permitem que duplas (versões falsas de Y) sejam definidas usando uma interface, para que seja possível injetar em uma instância de Y, onde Y é, por exemplo, uma conexão com o banco de dados.
É fácil cair na armadilha de acreditar que isso é puramente uma preocupação de teste de unidade, mas é um padrão muito útil para qualquer parte do código em que a mudança é esperada e, sem dúvida, é uma boa prática.
fonte
Fornecemos o comportamento de uma função em tempo de execução através do método de inserir esse comportamento na função por meio de um parâmetro
O Padrão de Estratégia é um excelente exemplo de injeção de dependência.
fonte
Para fazer isso direito, precisamos primeiro definir dependências e injeção.
Um exemplo rudimentar seria um método que adiciona dois valores. Obviamente, esse método precisa que os valores sejam adicionados. Se eles forem fornecidos passando-os como argumentos, isso já seria um caso de injeção de dependência. A alternativa seria implementar os operandos como propriedades ou variáveis globais. Dessa forma, nenhuma dependência seria injetada, as dependências estariam disponíveis externamente antecipadamente.
Suponha que você use propriedades e nomeie-as como A e B. Se você alterar os nomes para Op1 e Op2, você poderá interromper o método Add. Ou seu IDE atualizaria todos os nomes para você, o ponto é que o método precisaria ser atualizado também porque possui dependências de recursos externos.
Este exemplo é básico, mas você pode imaginar exemplos mais complexos em que o método executa uma operação em um objeto como uma imagem ou onde ele lê de um fluxo de arquivos. Deseja que o método alcance a imagem, exigindo que ela saiba onde está? Não. Deseja que o método abra o próprio arquivo, exigindo que ele saiba onde procurar o arquivo ou até mesmo que saiba que ele estará lendo um arquivo? Não.
O ponto: reduzir a funcionalidade de um método ao seu comportamento principal e separar o método do ambiente. Você obtém o primeiro fazendo o segundo; você pode considerar isso a definição de injeção de dependência.
Os benefícios: como as dependências para o ambiente do método foram eliminadas, as alterações no método não afetarão o ambiente e vice-versa. => O aplicativo fica mais fácil de manter (modificar).
fonte