ASP .NET Core - Injeção de Dependência via Método


  Neste artigo veremos como realizar a injeção de dependência via Método e Propriedade na ASP .NET Core usando o contêiner nativo.

Eu já tratei da injeção de dependência na ASP .NET Core usando o contêiner nativo aqui e aqui.

Hoje veremos como podemos realizar a injeção de dependência via método e também via propriedade.

Apenas para rever o conceito o contêiner nativo da ASP .NET Core é representando pela implementação IServiceProvider que ofere a injeção via construtor por padrão. Os tipos (classes) gerenciados pelo contêiner interno são chamados de serviços.

Assim, existem basicamente dois tipos de serviços no ASP.NET Core:

Para permitir que o contêiner IoC nativo  injete automaticamente nossos serviços, primeiro precisamos registrá-los no contêiner e geralmente usamos o método ConfigureServices da classe Startup para isso. Este método inclui o parâmetro do tipo IServiceCollection a qual é usado para fazer o registro.

Depois que registramos um serviço, o contêiner executa automaticamente a injeção do construtor se um tipo de serviço for incluído como parâmetro em um construtor.

Esse é a forma mais usada e a forma mais recomendada para realizar a injeção de dependência na ASP .NET Core.

Injeção via Método Action

Ocorre que podem existir situações nas quais a injeção via construtor não seja a ideal.

Imagine que precisamos que apenas um método Action dentro do nosso Controlador precise da dependência.

Neste caso basta fazer uma injeção local apenas neste método.

E tem como fazer isso ?

Sim, tem. 

A ASP.NET Core fornece um atributo chamado FromServices para injetar as dependências diretamente no método de Action do controlador.

A classe FromServicesAttribute pertence ao namespace Microsoft.AspNetCore.Mvc e pode ser usada para injetar um serviço diretamente em um método Action.

Assim o atributo FromServices, quando usado no seu controlador, especifica que um parâmetro em um método Action deve ser vinculado a um serviço do contêiner de serviços. Em outras palavras, quando você usa esse atributo em um método Action, o contêiner de serviços é usado para resolver as dependências em tempo de execução.

Vejamos isso funcionando na prática.

Recursos :

Criando o projeto no VS 2019 Community

Abra o VS 2019 Community e crie uma solução em branco via menu File-> New Project;

Selecione o template ASP .NET Core Web Application, e, Informe o nome Aspn_DIMetodo;

A seguir selecione .NET Core e ASP .NET Core 3.1 e marque o template Web Application(Model-View-Controller) e clique em Create.

Ao fintal teremos nossa aplicação ASP .NET Core MVC pronta.

Crie uma pasta Services no projeto e nesta pasta crie a interface ILog e sua implementação a classe ConsoleLogger:

1- ILog

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

2- ConsoleLogger

public class ConsoleLogger : ILog
{
    public bool RegistraLog(string texto)
    {
        Console.WriteLine(texto);
     }
}

A seguir temos que registrar esse serviço no método ConfigureServices da classe Startup:

  public void ConfigureServices(IServiceCollection services)
  {
            services.AddTransient<ILog, ConsoleLogger>();
            //outra for de registrar
            //services.AddSingleton(typeof(ILog), typeof(ConsoleLogger));
            services.AddControllersWithViews();
   }

Vamos agora ajustar o código do controlador HomeController na pasta Controllers.

Vamos alterar o código do método Action Index no controlador HomeController usando o atributo [FromServices] e a seguir injetando o serviço ILog que criamos:

using Aspn_DIMetodo.Models;
using Aspn_DIMetodo.Services;
using Microsoft.AspNetCore.Mvc;
using System.Diagnostics;
namespace Aspn_DIMetodo.Controllers
{
    public class HomeController : Controller
    {
        public IActionResult Index([FromServices] ILog log)
        {
            log.RegistraLog("Método Action Index em execução...");
            ViewBag.RegistraLog = "Método Action Index em execução...";
            return View();
        }
     ...
     ...
}

Pronto.

Executando o projeto iremos obter:

Uma outra alternativa e acessar os serviços dependentes configurados manualmente usando o contêiner nativo através da propriedade RequestServices do HttpContext que obtém ou define o IServiceProvider que fornece acesso ao contêiner de serviço da solicitação.

Nessa abordagem o código ficaria assim:

       public IActionResult Index()
        {
            var services = this.HttpContext.RequestServices;
            var meuLog = (ILog)services.GetService(typeof(ILog));

            meuLog.RegistraLog("Método Action Index em execução...");

            ViewBag.RegistraLog = "Método Action Index em execução...";
            return View();
       }

O resultado final é o mesmo.

Pegue o projeto completo aqui: Aspn_DIMetodo.zip  (sem as referências)

Disse Jesus: "Se, pois, o Filho vos libertar, verdadeiramente sereis livres."
João 8:36

Referências:


José Carlos Macoratti