Inversão de controle e injeção de dependência no asp.net core

Facebooktwittergoogle_plusredditpinterestlinkedinmail

Recentemente falamos aqui sobre Inversão de controle e injeção de dependência no .net core com uma aplicação aplicação console, e hoje vamos ver como trabalhar com injeção de dependência em uma aplicação web, utilizando asp.net core. E vocês vão ver que no asp.net fica ainda mais fácil de utilizar, pois não precisamos criar o container, o asp.net já faz isso para nós. Então vamos começar, abra o Visual Studio 2017, e crie uma ASP.NET Core Web Application (.NET Core) com o nome WebDemoDI, na tela seguinte selecione o template Web API. Com o projeto criado, vamos criar uma interface com o nome ICalculo com o código abaixo:

namespace WebDemoDI
{
    public interface ICalculo
    {
        double Calcular(double a, double b);
    }
}

E agora vamos fazer uma classe chamada Soma, que irá implementar nossa interface:

namespace WebDemoDI
{
    public class Soma : ICalculo
    {
        public double Calcular(double a, double b) => a + b;
    }
}

Agora para que nossa classe seja injetada quando solicitarmos, precisamos registrá-la, para isso abra a classe Startup, e no método ConfigureServices adicione o seguinte código:

services.AddTransient<ICalculo, Soma>();

A interface IServiceCollection é quem nos permite registrar nossas classes e interfaces no container do asp.net. Ela possui alguns métodos para registrar as classes, nós utilizamos o AddTransient, que define que toda vez que nós solicitarmos a interface ICalculo, o container vai criar uma nova instância da classe Soma e nos devolver. Poderíamos ter utilizado o método AddSingleton, que faz com que nossa classe seja criada uma única vez, e a mesma instância seja devolvida a cada solicitação. E por último, também tínhamos a opção de utilizar o método AddScoped, que cria uma nova instância da classe a cada request, reaproveitando a instância para solicitações dentro do mesmo request.

Dessa forma o método ConfigureServices ficou dessa forma:

public void ConfigureServices(IServiceCollection services)
{
	services.AddTransient<ICalculo, Soma>();
	services.AddMvc();
}

Agora crie um novo controller com o nome CalculosController, e adicione o código abaixo:

using System;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyInjection;

namespace WebDemoDI.Controllers
{
    [Route("api/[controller]")]
    public class CalculosController : Controller
    {
        private ICalculo calculo;
        private IServiceProvider serviceProvider;

        public CalculosController(ICalculo calculo, IServiceProvider serviceProvider)
        {
            this.calculo = calculo;
            this.serviceProvider = serviceProvider;
        }

        [HttpGet("{a}/{b}")]
        public double Get(double a, double b) => calculo.Calcular(a, b);

        [HttpGet]
        public double Get()
        {
            ICalculo soma = serviceProvider.GetService<ICalculo>();
            return soma.Calcular(100, 200);
        }
    }
}

O que fizemos aqui foi no construtor do controller pedirmos ao .net que nos forneça um objeto do tipo ICalculo e um do tipo IServiceProvider. O .net será responsável por criar uma instância de cada, seguindo as regras que foram definidas quando foram registradas com a interface IServiceCollection.

Na linha 20, também criamos um método Get, que recebe 2 parâmetros, e nele chamamos o método Calcular nossa inteface ICalculo, que tem uma instância da classe Soma, e retornamos esse valor.

E por fim, na linha 23, criamos um outro método Get, dessa vez que não recebe nenhum parâmetro, apenas para mostrar como fazer a injeção de dependência sem utilizar o construtor, e sim utilizando o método GetService de um IServiceProvider, que representa o container. Lembrando que o recomendado é utilizar o construtor da classe para fazer a injeção, e um dos motivos para isso é ganhar facilidade na hora de realizar os testes unitários.

Agora rode a aplicação e no browser digite o endereço:

http://localhost:52194/api/calculos/10/20

E você receberá como retorno 30.0. E se digitar apenas:

http://localhost:52194/api/calculos

Receberá como retorno o valor 300.0.

Como informei no post anterior, nós também podemos trocar o container utilizado pelo asp.net para injeção de dependência, e utilizar um de nossa preferência como o Autofac, e mostrarei como fazer isso em breve em um outro post.

Como já é costume aqui no blog, o código-fonte completo do exemplo está disponível no GitHub: https://github.com/rdakar/aspnet-core-di-primeiros-passos

Facebooktwittergoogle_plusredditpinterestlinkedinmail

1 thought on “Inversão de controle e injeção de dependência no asp.net core

Deixe uma resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *