Como você gerencia a configuração com injeção de dependência?


18

Sou um grande fã do DI / COI. É ótimo para lidar / abstrair dependências difíceis e facilitar a vida.

No entanto, eu tenho uma queixa pequena, que não tenho certeza de como resolver.

A idéia básica no DI / IOC é que, quando um objeto é instanciado, todas as suas dependências são preenchidas previamente no construtor.

No entanto, IMHO existem vários tipos de parâmetros para construtores (especialmente quando seus objetos são imutáveis).

  1. Dependências (objetos necessários para o seu objeto funcionar)
  2. Configuração (informações sobre o ambiente necessário para o trabalho)
  3. Parâmetros (dados em que o trabalho é realizado)

Acho que o COI funciona bem com dependências. Mas ainda estou tentando descobrir a melhor maneira de lidar com os outros dois. No entanto, como o construtor é executado para ser executado pelo contêiner do IOC, parece que preciso colocar esses itens no contêiner do IOC.

Gostaria de saber quais estratégias / padrões as pessoas empregam e quais vantagens e desvantagens as pessoas encontraram.

NB Estou ciente de que esta é uma questão altamente subjetiva e tentei torná-la uma "boa" questão subjetiva, de acordo com as diretrizes da SE.


Por "Configuração", você quer dizer a configuração do ambiente de desenvolvimento (como Desenvolvimento ou Produção)? Nesse caso, eu costumo lidar com isso como uma dependência tradicional.
— MetaFight

Melhor construir com dependências, mas com configuração padrão para que o objeto seja bem formado. Chame métodos adicionais para definir a configuração e outros parâmetros. Fazer muito no ctor é uma coisa ruim.
— David.pfx

I am still trying to work out the best way to deal with the other two- Passá-los como parâmetros comuns para o seu objeto?
— Robert Harvey

@RobertHarvey objetos imutáveis? Eles tornam a depuração muito mais fácil.
— ArTs

Respostas:


9

Configuração (informações sobre o ambiente necessário para o trabalho)

Crie uma classe de configuração (a ser exigente: uma interface + uma implementação) cujo objetivo é fornecer as informações sobre o ambiente. Isso faz com que a configuração não seja diferente de outros objetos necessários para o seu trabalho (ponto 1).

Parâmetros (dados em que o trabalho é realizado)

Em um ambiente orientado a objetos, tipos de dados primitivos podem ser encapsulados em objetos, portanto isso também leva ao ponto 1. Mas você provavelmente encontrará essa pergunta SO interessante, pois lida exatamente com a situação dos parâmetros primitivos em um construtor, ao usar um DI recipiente. No exemplo dado, o design poderia ser aprimorado, o que evitava completamente a necessidade de tipos primitivos no construtor.


1

O que faço é um padrão de fábrica para esses casos.

Eu não uso o próprio objeto como uma dependência, mas crio um objeto de fábrica com um método Get que aceita parâmetros que não podem ser vinculados automaticamente pelo contêiner.

Ex.:

 interface IDependencyObject {
       ....
 }

 class DependencyObject {

      public DependencyObject(int primitive, IAnotherDependency anotherDependency) {
      ...
      }

 }

 class DependencyObjectFactory {

      private readonly IAnotherDependency anotherDependency;

      public DependencyObjectFactory(IAnotherDependency anotherDependency) {
           this.anotherDependency = anotherDependency;
      }

      public IDependencyObject Get(int primitive) {
           return new DependencyObject(primitive, anotherDependency);
      }
 }

 interface IDependencyObjectFactory {
       IDependencyObject Get(int primitive);
 }
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.