Utilizando interfaces, inversão de controle e injeção de dependências em programação - Um exemplo em C#

        A melhor forma que encontrei para entender e explicar os conceitos de interfaces, inversão de controle e injeção de dependências é através de exemplo. Este exemplo tirei de um curso que pode ser verificado nas referências desta postagem.
        O exemplo trata do cálculo de impostos e do valor total cobrado do cliente em uma empresa fictícia de aluguel de veículos. O valor da taxa de imposto varia caso o aluguel seja por dia ou por hora. O valor calculado sempre é arredondado para mais. As entradas que damos ao sistemas são:
- data e horário da retirada do veículo
- data e horário da devolução do veículo
- preço do aluguel por hora
- preço do aluguel por dia

        Executando a aplicação:
 

        No github, dividi a solução em dois commits diferentes. Um para a solução sem uso de interfaces e outro com o uso da interface. Dado o código e o funcionamento geral, vamos nos concentrar nas diferenças entre as soluções para entender os conceitos. 
        Na primeira implementação, RentalService depende fortemente de BrazilTaxService, ou seja, se houver uma mudança ou troca do serviço de impostos, será necessário modificar a classe RentalService. Com isso, dizemos que a classe RentalService não está fechada para alterações. Isso é indesejável, pois gera retrabalho com chance de erros caso desejemos mudar o TaxService para cálculo de impostos em outro país com outra alíquota, por exemplo. Além disso está em desacordo com os princípios SOLID. 
        É aí que entram as interfaces. A interface define apenas um contrato que o serviço de imposto deverá cumprir. A partir disso, podemos criar  serviços específicos que implementem a interface. Exemplo, o BrazilTaxService que implementa ITaxService (que é a interface que por padrão começa com "I"). O arquivo da interface é bastante simples:


            As mudanças principais estão em RentalService.cs


        Na linha 11 acima, vemos a substituição da instanciação de _brazilTaxService por _taxService da interface criada anteriormente. Ao realizar essa troca, estamos diminuindo o acoplamento da aplicação, pois a interface ITaxService pode ser implementada por qualquer serviço que respeite a interface, por exemplo poderíamos criar _argentinaTaxService. Repare que aqui retiramos a instanciação, que foi passada para o construtor na linha 13 que agora espera receber um taxService. 
        Muita atenção nessa inclusão, pois com ela estamos fazendo uma inversão de controle. A inversão de controle consiste exatamente em retirar da classe a responsabilidade de instanciar suas dependências (aqui no caso, brazilTaxService). Essa troca deve ficar explicita também na declaração de tax, que passa a utilizar apenas a genérica _taxService, mudança realizada na linha 34. 
        E como a classe saberá qual serviço utilizará se nós colocamos um serviço genérico? Bom, lembra do construtor que passou a receber o parâmetro ITaxService? Então, ali diz-se que a classe está recebendo o parâmetro via injeção de dependência, que é injetada no objeto "pai". A injeção de dependência pode ser implementada de várias formas: construtor, objeto de instanciação ou container/framework. 
        Outra mudança necessária é na implementação do serviço BrazilTaxService. Da mesma forma como fazemos em herança, vamos declarar que essa classe implementa ITaxService.


        Finalmente, na instanciação via construtor de rentalService, vamos injetar a dependência BrazilTaxService.


        Com isso, nesta explicação espero que tenha ficado mais claro os conceitos de interfaces, inversão de controle e injeção de dependências. Para mim ficou, me diga se para você leitor, também! Até a próxima!

Referências:

ALVES, Nelio. C#Completo 2020 Programação Orientada a Objetos + Projeto. Disponível em: 
<https://www.udemy.com/course/programacao-orientada-a-objetos-csharp/>

Comentários

Postagens mais visitadas deste blog

Como utilizar Tag Prefix WinCC Professional

TUTORIAL: Criando WinCC Tags a partir de documentos de texto utilizando script em Python