Injeção de Dependência (Dependency Injection - DI)
Injeção de Dependência é um padrão de design que permite que objetos recebam suas dependências de uma fonte externa ao invés de criarem-nas diretamente. Isso facilita o gerenciamento das dependências e promove um código mais modular, testável e fácil de manter.
Conceitos Básicos
Dependência: Uma dependência é qualquer objeto que uma classe precisa para funcionar. Por exemplo, se uma classe
Car
depende de um objetoEngine
para funcionar,Engine
é uma dependência deCar
.Injeção: O ato de fornecer a dependência necessária para uma classe. Existem três tipos principais de injeção de dependência:
- Injeção por Construtor: A dependência é passada através do construtor da classe.
- Injeção por Propriedade: A dependência é passada através de uma propriedade pública da classe.
- Injeção por Método: A dependência é passada através de um método.
Contêiner de DI do ASP.NET Core
O ASP.NET Core possui um contêiner de injeção de dependência embutido que gerencia a criação e o ciclo de vida dos objetos. Este contêiner é responsável por resolver e fornecer as dependências necessárias quando necessário.
Funções do Contêiner de DI
Registro de Serviços: Os serviços (dependências) são registrados no contêiner para que possam ser resolvidos mais tarde. Isso geralmente é feito no método
ConfigureServices
da classeStartup
ou na configuração do builder noProgram.cs
.Resolução de Dependências: Quando uma classe precisa de uma dependência, o contêiner resolve essa dependência e a injeta na classe. Isso pode ser feito automaticamente pelo framework quando a classe é instanciada ou manualmente quando necessário.
Exemplo
Configuração no Program.cs
No ASP.NET Core 6+, a configuração de serviços é feita no arquivo Program.cs
:
var builder = WebApplication.CreateBuilder(args);
// Registro de serviços no contêiner de DI
builder.Services.AddTransient<IMyService, MyService>();
var app = builder.Build();
app.Run();
Interface e Implementação
Defina uma interface e sua implementação:
public interface IMyService
{
void DoSomething();
}
public class MyService : IMyService
{
public void DoSomething()
{
Console.WriteLine("Doing something...");
}
}
Usando a Dependência
Você pode usar a dependência em um controller ou outro serviço via injeção de dependência:
public class MyController : ControllerBase
{
private readonly IMyService _myService;
public MyController(IMyService myService)
{
_myService = myService;
}
[HttpGet]
public IActionResult Get()
{
_myService.DoSomething();
return Ok();
}
}
Tipos de Ciclo de Vida de Serviços
Ao registrar serviços, você pode especificar o ciclo de vida deles:
Transient: Criado cada vez que é solicitado. Use para serviços leves e sem estado.
builder.Services.AddTransient<IMyService, MyService>();
Scoped: Criado uma vez por solicitação (request). Use para serviços que mantêm estado dentro de uma solicitação.
builder.Services.AddScoped<IMyService, MyService>();
Singleton: Criado uma vez e compartilhado em toda a aplicação. Use para serviços que mantêm estado compartilhado.
builder.Services.AddSingleton<IMyService, MyService>();
Vantagens da Injeção de Dependência
- Facilidade de Testes: Facilita a criação de testes unitários, permitindo a substituição de dependências por versões simuladas (mock).
- Baixo Acoplamento: Reduz o acoplamento entre classes, permitindo que mudem independentemente umas das outras.
- Melhor Manutenibilidade: Promove um código mais limpo e fácil de manter.
Em resumo, a injeção de dependência no ASP.NET Core, com seu contêiner de DI embutido, oferece uma maneira eficiente e flexível de gerenciar e resolver dependências, promovendo boas práticas de design de software.