Já falamos sobre injeção de dependência e inversão de controle por aqui anteriormente, sendo que falamos de dois dos muitos containers disponíveis para .net, o Autofac, que é um dos mais utilizados e conhecidos, e do DryIoC, que apesar de não ser tão famoso, é muito leve e rápido. E hoje vamos ver como utilizar a injeção de dependência no .net core, que agora traz um container nativo, não necessitando mais que você adicione um em seu projeto. Apesar de vir com um container nativo, o .net core permite que você troque o container por um de sua preferência caso queira, como por exemplo o Autofac, e essa troca e simples e fácil, mas veremos isso em outro post.
Então vamos colocar a mão na massa e ver como é fácil utilizar DI no .net core. Crie uma Console App (.NET Core) no Visual Studio 2017, e de o nome de DemoDI. Agora vamos criar um interface com o nome ICalculo com o seguinte código:
namespace DemoDI { public interface ICalculo { double Calcular(double a, double b); } }
Agora vamos criar uma classe para implementar nossa interface, e vamos chamá-la de Soma:
namespace DemoDI { public class Soma : ICalculo { public double Calcular(double a, double b) => a + b; } }
Agora vamos criar outra classe que implemente a interface ICalculo, e vamos chamá-la de Subtracao:
namespace DemoDI { public class Subtracao : ICalculo { public double Calcular(double a, double b) => a - b; } }
Agora vamos criar uma classe chamada Calculadora, que receberá uma lista de objetos que implementem a interface ICalculo como parâmetro no construtor, e executará os cálculo com os valores informados para cada objeto recebido, o seu código ficará dessa forma:
using System; using System.Collections.Generic; namespace DemoDI { public class Calculadora { private readonly IEnumerable<ICalculo> calculos; public Calculadora(IEnumerable<ICalculo> calculos) { this.calculos = calculos; } public void EfetuarCalculo(double a, double b) { foreach (var calculo in calculos) { var result = calculo.Calcular(a, b); Console.WriteLine($"Resultado: {result}"); } } } }
Agora precisamos adicionar o pacote de injeção de dependência em nosso projeto, para isso digite o comando abaixo no console do Nuget:
Install-Package Microsoft.Extensions.DependencyInjection
Agora temos acesso às classes do container em nosso projeto, e vamos alterar a classe Program, para criarmos nosso container, e utilizarmos nossos objetos. A primeira coisa que iremos fazer é criar nosso container e registrar as classes que criamos, para isso adicione as linhas abaixo dentro do método Main:
IServiceCollection collection = new ServiceCollection(); collection.AddTransient<ICalculo, Soma>(); collection.AddTransient<ICalculo, Subtracao>(); collection.AddSingleton<Calculadora>(); IServiceProvider serviceProvider = collection.BuildServiceProvider();
O que fizemos aqui foi primeiro criar um IServiceCollection, que é quem nos permite registrar nossas classes, depois registramos nossas classes Soma e Subtracao, para serem utilizadas quando um objeto do tipo ICalculo for solicitado, e para isso utilizamos o método AddTransient, que faz com que a cada solicitação, seja criado um novo objeto. Depois registramos nossa classe Calculadora, que não possui interface, então ela será devolvida toda vez que alguém solicitar diretamente pela classe, e como fizemos seu registro utilizando o método AddSingleton, nossa classe será criada apenas uma vez, e sempre que alguém solicitá-la, a mesma cópia será devolvida. E por fim, na última linha, criamos um objeto do tipo IServiceProvider, que é nosso container, sendo ele o responsável por fornecer os objetos toda vez que for solicitado.
Agora vamos pedir ao container que nos forneça um objeto do tipo Calculadora, para isso faremos o seguinte:
Calculadora calculadora = serviceProvider.GetService<Calculadora>();
Sempre que quisermos pedir um objeto ao container, nós utilizamos o método GetService, informando o tipo desejado e o container irá nos fornecer.
Agora vamos efetuar um cálculo e ver o que acontece? Então adicione a linha abaixo:
calculadora.EfetuarCalculo(10, 20);
E por fim, adicione também a linha:
Console.Read();
Rode a aplicação e você verá no console a informação abaixo:
Resultado: 30 Resultado: -10
Veja que nossa calculadora efetuou uma soma e uma subtração com os valores que informamos, agora, como isso ocorreu, se em momento nenhum informamos na sua criação a lista de objetos do tipo ICalculo. A lista foi injetada pelo construtor da classe, pois recebe um IEnumerable<ICalculo>. Como temos registrado mais de uma classe que implementa uma interface, ao pedir para o container um IEnumerable<ICalculo> ele vai nos devolver todos objetos que implementem a interafce, e fazer a injeção.
Lembrando que é uma boa prática a injeção de dependência através de construtores, e sempre que possível deve ser utilizada, evitando a chamada ao container de forma explícita como fizemos para criar a calculadora dentro da função Main, mas vão ter situações que a chamada explícita fará sentido, por isso mostramos aqui. Um dos motivos da injeção via construtores ser recomendada, é por facilitar a criação de testes.
O código completo da classe Program ficou dessa forma:
using System; using Microsoft.Extensions.DependencyInjection; namespace DemoDI { class Program { static void Main(string[] args) { IServiceCollection collection = new ServiceCollection(); collection.AddTransient<ICalculo, Soma>(); collection.AddTransient<ICalculo, Subtracao>(); collection.AddSingleton<Calculadora>(); IServiceProvider serviceProvider = collection.BuildServiceProvider(); Calculadora calculadora = serviceProvider.GetService<Calculadora>(); calculadora.EfetuarCalculo(10, 20); Console.Read(); } } }
O código completo da aplicação está disponível no GitHub no endereço: https://github.com/desenvolvedorninja/dotnet-core-di-primeiros-passos

Quase 20 anos de experiência no mercado de TI.
Atuação em grandes empresas como Netshoes, Borland, JBS, Bradesco, Hospital das Clínicas, Rede, Prodam, HSPE, Instituto Ayrton Senna, e também em empresas internacionais como Delta Dental, T-Mobile, Pepsi e Mckesson.
Fundador da TecPrime Solutions, administrador da comunidade nopCommerce Brasil, e autor dos sites InvestFacil.net e Desenvolvedores.ninja
3 thoughts on “Inversão de controle e injeção de dependência no .net core”