Continuamos a série “Padrões de DI”, mostrando uma terceira forma de injetarmos dependências: Method Injection.

1. O QUE É

Como o próprio nome diz, Method Injection é um padrão de DI que consiste em fornecer a dependência como parâmetro de um método.

2. QUANDO USAR

Ao contrário de Constructor Injection e Property Injection, com Method Injection, a dependência não é resolvida em um Composition Root e sim, em tempo de invocação do método.

Em outras palavras, nós já temos uma instância da dependência e desejamos passá-la adiante para algum consumidor. Portanto, ele se adequa bem quando, para cada chamada do método, precisamos passar uma implementação diferente da dependência.

3. COMO IMPLEMENTAR

A implementação é trivial (o exemplo é meramente didático):

public class SimuladorDeInadimplencia
{
   //.....

   // dependência IEstrategiaDeReajuste 
   // passada por parâmetro
   public IEnumerable<ParcelaReajustada> Aplicar(
          IEstrategiaDeReajuste reajuste)
   {
      // guard-clause
      if (reajuste == null)
          throw new ArgumentNullException("reajuste");
   
      var parcelasVencidas =
          this.parcelaRepositorio.ObterAsVencidas();

      // utilização da dependência para
      // gerar uma parcela reajustada
      return parcelasVencidas
          .Select(p => reajuste.AplicarEm(p));
   }
}

Simples, não?

Ao receber a dependência como parâmetro, estamos deixando claro que ela é exigida apenas naquele método, além de permitirmos que instâncias diferentes sejam passadas ao mesmo objeto Simulador, sem a necessidade de instancia-lo novamente:

// alguma classe que usa o simulador
//.....
var estrategiasDeReajuste = ObterTodas();
foreach(var estrategia in estrategiasDeReajuste)
{
   var parcelasReajustadas =
       this.simulador.Aplicar(estrategia);

   FazAlgo(parcelasReajustadas);
}
//.....

(O conjunto de estratégias poderia ser criada a partir da entrada do usuário ou de um arquivo de configuração.)

4. CONCLUSÃO

Com Method Injection já possuímos a dependência e queremos passá-la adiante (como parâmetro) para seu consumidor.

É menos comum que Constructor Injection e Property Injection, mas é uma boa opção principalmente quando queremos variar a implementação da dependência para o mesmo objeto consumidor.

No próximo artigo, encerro esta série com outro padrão, ainda mais específico.