C# -
Dependency Injection via Console .NET Core
![]() |
Neste artigo veremos realizar a injeção de dependência em uma aplicação Console .NET Core usando o container nativa da ASP .NET Core. |
Um dos principais recursos da ASP.NET Core é a injeção de dependência nativa feita pelo seu container.
![]() |
Você pode usar um contêiner de terceiro que tenha mais recursos se precisar fazer coisas como: registro baseado em convenções, ferramentas de registro/depuração ou abordagens mais esotéricas, como injeção de propriedade.
No entanto, para projetos pequenos o contêiner nativo dá conta do recado de forma bem simples.
Uma das vantagens do contêiner interno na ASP.NET Core é que as próprias bibliotecas do framework registram suas dependências. Quando você chama o método de extensão AddMvc() no método Startup.ConfigureServices, o framework registra uma infinidade de serviços no contêiner. Se você adicionar posteriormente um contêiner de terceiros, essas dependências serão repassadas para serem registradas novamente, para que fiquem disponíveis quando resolvidas por terceiros.
Os serviços mais comuns criados para uso com a ASP.NET Core terão extensões para registro no contêiner interno via IServiceCollection; portanto, se você estiver usando serviços como log ou padrão de opções, certamente será mais fácil usar as extensões fornecidas e se conectar a um plugin de terceiro, se necessário.
Se você estiver escrevendo um aplicativo de console, provavelmente não precisará do serviço MVC ou de outros serviços específicos da ASP.NET Core. Nesse caso, pode ser igualmente fácil começar imediatamente usando outro framework como StructureMap ou o AutoFac, em vez do provedor interno que é mais limitado.
E agora vem a pergunta: "Posso usar o provedor interno em uma aplicação Console do .NET Core ?
A resposta curta é : 'ele não esta pronto para ser
usado', mas você pode adicioná-lo ao seu projeto
Console.
Então vejamos como fazer isso...
Adicionando a Injeção de dependência a uma aplicação Console
Adicionar o contêiner interno da ASP .NET Core em seu projeto Console é muito simples.
Primeiro crie um projeto Console do tipo .NET Core no VS 2019 ou no VS Code. Vou usar o VS 2019 Community.
A seguir inclua o seguinte pacote no seu projeto:
pacote Microsoft.Extensions.DependencyInjection;
A título de exemplo vamos criar dois serviços em nosso projeto.
Crie uma pasta Services no projeto e nesta pasta crie a interface IDemoService:
public interface IDemoService
{
void ServicoDemo(int numero);
}
|
Na mesma pasta crie a interface ITesteService :
public interface ITesteService
{
void ServicoTeste();
}
|
Vamos agora criar na mesma pasta as implementações DemoService() e TesteService() destes serviços de forma que o serviço ITesteService dependa de um serviço IDemoService.
1- TesteService
public class TesteService : ITesteService { private readonly IDemoService _demoService; public TesteService(DemoService demoService) { _demoService = demoService; } public void ServicoTeste()
{
for (int i = 0; i < 10; i++)
{
_demoService.ServicoDemo(i);
}
}
}
|
2- DemoService
using System; public class DemoService : IDemoService
{
public void ServicoDemo(int numero)
{
Console.WriteLine($"Realizando operação : {numero}");
}
}
|
Vamos agora usar o método Main da classe Program para por as coisas para funcionar...
using CShp_ConsoleDI.Services;
using Microsoft.Extensions.DependencyInjection;
using System;
class Program
{
static void Main(string[] args)
{
//configura nossa injeção de dependencia
var serviceProvider = new ServiceCollection()
.AddSingleton<ITesteService, TesteService>()
.AddSingleton<IDemoService, DemoService>()
.BuildServiceProvider();
Console.WriteLine("Iniciando Aplicação");
//realiza a operação
var teste = serviceProvider.GetService<ITesteService>();
teste.ServicoTeste();
Console.WriteLine("Operação Concluida!");
Console.ReadLine();
}
}
|
Assim vemos que para aproveitar a estrutura da DI do .NET Core, só precisamos é de uma referência para o pacote NuGet Microsoft.Extensions.DependencyInjection.
Isso fornece acesso à interface IServiceCollection, que expõe um System.IServiceProvider a partir do qual você pode chamar GetService<TService>. O parâmetro de tipo, TService, identifica o tipo do serviço a recuperar (geralmente uma interface).
Executando o projeto iremos obter o seguinte resultado:
Vamos entender o código...
Primeiro configuramos o contêiner de injeção de dependência criando um ServiceCollection, e, adicionando as nossas dependências que no nosso caso são os registros dos nossos serviços e suas dependências, e ao final criamos um IServiceProvider:
var serviceProvider = new ServiceCollection()
.AddSingleton<ITesteService, TesteService>()
.AddSingleton<IDemoService, DemoService>()
.BuildServiceProvider();
Esse processo é equivalente ao que fazemos no método ConfigureServices em um projeto ASP.NET Core e é basicamente o que acontece nos bastidores.
Note que estamos
usando o método de extensão IServiceCollection para
adicionar os serviços ao nosso aplicativo e depois registrar nossos próprios
serviços. O serviceProvider é nosso contêiner que
podemos usar para resolver serviços em nosso aplicativo.
O restante do programa mostra mais injeção de dependência em andamento.
Primeiro, buscamos uma instância do ITesteService. De acordo com nossos registros, o ITesteService é uma instância do TesteService, que terá uma instância do DemoService injetada.
Observou que o contêiner detectou a necessidade do serviço DemoService para funcionamento do serviço TesteService...
Podemos ter um código mais estruturado e robusto organizando o código conforme exemplo abaixo:
class Program
{
private static IServiceProvider _serviceProvider;
static void Main(string[] args)
{
RegisterServices();
var service = _serviceProvider.GetService<IDemoService>();
service.ServicoDemo();
DisposeServices();
}
private static void RegisterServices()
{
var collection = new ServiceCollection();
collection.AddScoped<IDemoService, DemoService>();
// ...
// e outros serviços
// ...
_serviceProvider = collection.BuildServiceProvider();
}
private static void DisposeServices()
{
if(_serviceProvider == null)
{
return;
}
if (_serviceProvider is IDisposable)
{
((IDisposable)_serviceProvider).Dispose();
}
}
}
|
E é assim que podemos usar a injeção de dependência usando o contêiner nativa da ASP .NET Core.
Na próxima parte do artigo veremos os ciclos de vida dos serviços injetados.
Pegue o projeto
aqui:
CShp_ConsoleDI.zip
"No princípio
era o Verbo, e o Verbo estava com Deus, e o Verbo era Deus.
Ele estava no princípio com Deus.
Todas as coisas foram feitas por ele, e sem ele nada do que foi feito se fez."
João 1:1-3
Referências: