Olá, galera

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

Vamos direto ao assunto:

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 estrategiaDeReajuste)
    {
        // guard-clause
        if (estrategiaDeReajuste == null) throw new ArgumentNullException("estrategiaDeReajuste");

        // utilização da dependência para gerar uma parcela reajustada
        var parcelasVencidas = this.parcelaRepositorio.ObterAsVencidas();
        return parcelasVencidas.Select(parcela => estrategiaDeReajuste.AplicarEm(parcela));
    }
}

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. CONCLUINDO

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.

Até lá!