Container de Injeção de Dependência para C# (.NET): guia completo
Injeção de Dependência (DI) é um dos principais padrões de projeto no desenvolvimento moderno com C# e .NET. Ele permite criar aplicações fracamente acopladas, testáveis e de fácil manutenção. Neste artigo, veremos detalhadamente o que é um container de Injeção de Dependência, como usá-lo no .NET e apresentaremos exemplos práticos de código.
O que é Injeção de Dependência?
Injeção de Dependência (Dependency Injection) é um padrão no qual um objeto recebe suas dependências externamente, em vez de criá-las por conta própria. Isso permite:
- Reduzir o acoplamento entre componentes
- Simplificar os testes (possibilidade de substituir dependências por mocks)
- Aumentar a flexibilidade e reutilização do código
- Centralizar o gerenciamento do ciclo de vida dos objetos
O que é um container DI?
Um container DI (ou container IoC) é uma biblioteca que automatiza o processo de injeção de dependências. Ele assume a responsabilidade de criar objetos e gerenciar seu tempo de vida. No .NET, o principal container DI é o Microsoft.Extensions.DependencyInjection, que é integrado ao ASP.NET Core e pode ser usado em qualquer aplicação .NET.
Conceitos principais do container DI
O container DI opera com os seguintes conceitos:
- Registro de serviços — processo de adicionar tipos e suas implementações ao container
- Resolução de dependências — criação automática de objetos com suas dependências
- Tempo de vida dos serviços — define por quanto tempo o objeto existe (Transient, Scoped, Singleton)
Configuração do container DI no .NET
Para começar a usar o container DI, é necessário instalar o pacote Microsoft.Extensions.DependencyInjection. Isso pode ser feito via NuGet:
dotnet add package Microsoft.Extensions.DependencyInjectionApós a instalação, cria-se uma instância de ServiceCollection, onde todas as dependências são registradas:
using Microsoft.Extensions.DependencyInjection;
// Criamos uma coleção de serviçosvar services = new ServiceCollection();
// Registramos os serviçosservices.AddTransient<ILogger, ConsoleLogger>();services.AddScoped<IUserRepository, UserRepository>();services.AddSingleton<IConfiguration, AppConfiguration>();
// Construímos o provedor de serviçosvar serviceProvider = services.BuildServiceProvider();Exemplo de uso do container DI
Vamos considerar um exemplo real: uma aplicação para gerenciamento de usuários. Criaremos interfaces e suas implementações:
public interface IUserRepository{ User GetUser(int id);}
public interface IEmailService{ void SendEmail(string to, string subject);}
public class UserRepository : IUserRepository{ public User GetUser(int id) { // Lógica para obter usuário do banco de dados return new User { Id = id, Name = "John Doe" }; }}
public class EmailService : IEmailService{ public void SendEmail(string to, string subject) { Console.WriteLine($"Email enviado para {to}: {subject}"); }}Agora, criaremos a classe UserService, que utiliza essas dependências:
public class UserService{ private readonly IUserRepository _userRepository; private readonly IEmailService _emailService;
public UserService(IUserRepository userRepository, IEmailService emailService) { _userRepository = userRepository; _emailService = emailService; }
public void NotifyUser(int userId) { var user = _userRepository.GetUser(userId); _emailService.SendEmail(user.Email, "Bem-vindo!"); }}Registramos tudo no container DI
Também na biblioteca
Tokens JWT em Go (Golang): biblioteca golang-jwt e exemplos de uso
Bibliotecas WebSocket TypeScript: ws, Socket.IO, uWebSockets.js
Rate Limiting em Swift: gerenciamento de frequência de requisições em iOS/macOS
Autorização e Autenticação em C++: Bibliotecas, Exemplos e Implementação
Trabalho com XML em Swift: parsing, criação e processamento de dados (iOS/macOS)