C# - Inversão da Dependência


 Neste artigo vamos recordar o conceito da inversão da dependência na POO.

O mantra do paradigma da Programação orientada a objetos (POO) afirma que a direção da dependência em uma aplicação deve estar na direção da abstração, não nos detalhes da implementação.

A maioria dos aplicativos é criada de forma que a dependência em tempo de compilação flua na direção da execução do runtime. Isso produz um gráfico de dependência direta.

Assim, se o módulo A chamar uma função/método no módulo B, que chama uma função/método no módulo C, em tempo de compilação A dependerá de B, que dependerá de C, como mostrado abaixo:

Podemos mudar isso aplicando o princípio da inversão de dependência que diz o seguinte:

"Dependa de abstrações e não de implementações"
"Módulos de alto nível não devem depender de módulos de baixo nível. Ambos devem depender de abstrações"
"Abstrações não devem depender de detalhes. Detalhes devem depender de abstrações"

São três definições que querem dizer a mesma coisa:
 "Programe para uma interface/classe abstrata e não para uma classe concreta."

A aplicação do princípio de inversão de dependência permite que a classe A chame métodos em uma abstração implementada por B, possibilitando que A chame B em tempo de execução, mas que B dependa de uma interface controlada por A em tempo de compilação (invertendo assim a dependência em tempo de compilação).

Em tempo de execução, o fluxo de execução do programa permanece inalterado, mas a introdução de interfaces significa que diferentes implementações dessas interfaces podem ser facilmente conectadas.

Assim a inversão de dependência é uma parte essencial da construção de aplicativos fracamente acoplados, pois os detalhes da implementação podem ser escritos para depender e implementar abstrações de nível superior, e não o contrário.

Os aplicativos resultantes são mais testáveis, modulares e sustentáveis como resultado.

Assim os principais motivos para programar para uma interface/classe abstrata são:

Além disso interfaces facilitam a redução do acoplamento do código e ajudam a encapsular o código.

Como podemos obter a inversão da dependência ?

Uma das formas de obter a inversão da dependência e usar o padrão de projeto da injeção da dependência.

Assim, injetamos a dependência para obter a inversão da dependência.

Como exemplo temos o framework ASP .NET Core que injeta objetos de classes de dependência por meio de construtor ou método usando o contêiner IoC interno.

Assim, na ASP .NET Core , basta criar e registrar o seu serviço usando abstrações onde geralmente criamos uma interface e uma classe concreta que implementa esta interface.

Como exemplo temos a interface ILog e a classe ConsoleLogger que a implementa:

public interface ILog
{
    void info(string texto);
}

class ConsoleLogger : ILog
{
    public void info(string texto)
    {
        Console.WriteLine(texto);
    }
}

A seguir a ASP.NET Core permite registrar nossos serviços de aplicativo no contêiner IoC, no método ConfigureServices da classe Startup.

Este método inclui um parâmetro do tipo IServiceCollection que é usado para registrar serviços de aplicativos.

Vamos registrar acima do ILog com o container IoC no método ConfigureServices(), como mostrado abaixo.

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddSingleton(ILog,ConsoleLogger));        
    }
    // código...
}

Acima vemos o método AddSingleton da instância IServiceCollection sendo usado para registrar um serviço  em um contêiner de IoC.

Especificamos ILog como tipo de serviço e ConsoleLogger como sua instância. Isso registrará o serviço ILog como um serviço com tempo de vida Singleton por padrão. Agora, um contêiner de IoC criará um objeto singleton da classe ConsoleLogger e o injetará no construtor de classes, sempre que incluirmos o ILog como construtor ou parâmetro de método em todo o aplicativo.

Assim, podemos registrar nossos serviços de aplicativos personalizados com um contêiner de IoC no aplicativo ASP.NET Core. Existem outros métodos de extensão disponíveis para o registro rápido e fácil de serviços, que veremos mais adiante neste capítulo.

Assim como fez a ASP .NET Core podemos usar qualquer outro framework para realizar a injeção de dependência e assim obter a inversão de dependência desacoplando o código.

E estamos conversados.

"Portanto, cingindo os lombos do vosso entendimento, sede sóbrios, e esperai inteiramente na graça que se vos ofereceu na revelação de Jesus Cristo;"
1 Pedro 1:13


Referências:


José Carlos Macoratti