Fundamentos do contêiner de DI
Entenda a inversão de controle, o registro de serviços e como o contêiner de DI do .NET resolve dependências.
Fundamentos do contêiner de DI é uma aula grátis de C# Academy no CoddyKit. Esta é a aula 1 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de C# Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de C# Academy inclui 4 aulas no total.
O que é injeção de dependências?
Injeção de dependências (DI) é um padrão de projeto no qual uma classe recebe suas dependências de uma fonte externa, em vez de criá-las por conta própria.
Em vez de escrever var repo = new UserRepository(); dentro de uma classe, a classe declara do que precisa e o contêiner de DI fornece isso.
Inversão de controle
DI é uma implementação concreta do princípio da inversão de controle (IoC): o controle da criação das dependências é invertido da classe dependente para um contêiner externo.
Isso torna as classes mais fáceis de testar e substituir.
Configurando o contêiner de DI do .NET
Em um aplicativo .NET, o contêiner de DI é configurado por meio de IServiceCollection em Program.cs. Os serviços são registrados e, em seguida, resolvidos pelo tempo de execução.
var builder = WebApplication.CreateBuilder(args);
// Register services
builder.Services.AddScoped<IUserRepository, UserRepository>();
builder.Services.AddScoped<UserService>();
var app = builder.Build();
app.Run();Definindo uma interface e uma implementação
A DI funciona melhor quando você programa para interfaces. Defina uma interface para o contrato do serviço e uma classe concreta que o implemente.
public interface IUserRepository
{
User? GetById(int id);
}
public class UserRepository : IUserRepository
{
public User? GetById(int id)
{
// fetch from database
return new User { Id = id, Name = "Alice" };
}
}Resolvendo serviços por meio do construtor
O contêiner injeta automaticamente os serviços registrados nos construtores. A classe só precisa declarar a interface de que precisa — não é necessária a palavra-chave new.
public class UserService
{
private readonly IUserRepository _repo;
public UserService(IUserRepository repo)
{
_repo = repo;
}
public User? FindUser(int id) => _repo.GetById(id);
}Registrando vários serviços
Você pode registrar quantos serviços forem necessários. Os métodos de extensão mais comuns são AddTransient, AddScoped e AddSingleton — cada um define um ciclo de vida diferente.
builder.Services.AddSingleton<IConfig, AppConfig>();
builder.Services.AddScoped<IUserRepository, UserRepository>();
builder.Services.AddTransient<IEmailService, SmtpEmailService>();
builder.Services.AddScoped<UserService>();Usando IServiceProvider diretamente
Em casos raros, é necessário resolver serviços de forma imperativa. IServiceProvider permite chamar GetRequiredService<T>() para resolver um serviço, mas prefira a injeção pelo construtor na maioria dos cenários.
// Anti-pattern (service locator) — use sparingly
public class ManualResolver
{
private readonly IServiceProvider _sp;
public ManualResolver(IServiceProvider sp) => _sp = sp;
public void DoWork()
{
var svc = _sp.GetRequiredService<UserService>();
svc.FindUser(1);
}
}Registrando genéricos abertos
A DI do .NET oferece suporte a registros de genéricos abertos. Você pode registrar IRepository<> uma vez, e ele será resolvido como Repository<T> para qualquer tipo de entidade.
builder.Services.AddScoped(typeof(IRepository<>), typeof(Repository<>));
// Resolves as:
// IRepository<User> -> Repository<User>
// IRepository<Order> -> Repository<Order>Validação na inicialização
Com ValidateOnStart() ou ValidateScopes = true, o contêiner pode detectar registros configurados incorretamente (como capturar um serviço com escopo dentro de um serviço de instância única) na inicialização do aplicativo, em vez de fazê-lo em tempo de execução.
builder.Services.AddScoped<IMyService, MyService>();
// Detect scope violations at startup
builder.Host.UseDefaultServiceProvider(options =>
{
options.ValidateScopes = true;
options.ValidateOnBuild = true;
});Decorando serviços
Você pode envolver um serviço com um decorador sem modificar a classe original. Primeiro registre o serviço interno e, depois, registre o decorador que o envolve.
builder.Services.AddScoped<IUserRepository, UserRepository>();
// Decorator pattern
builder.Services.Decorate<IUserRepository, CachedUserRepository>();
// Requires Scrutor NuGet packageNa prática: API mínima com DI
Em uma API mínima, os serviços são injetados diretamente nos parâmetros do manipulador de rotas. O contêiner os resolve automaticamente.
app.MapGet("/users/{id}", (int id, UserService svc) =>
{
var user = svc.FindUser(id);
return user is null ? Results.NotFound() : Results.Ok(user);
});Verificação rápida
Qual método você deve preferir para obter dependências na maioria das classes?
Recapitulação: fundamentos do contêiner de DI
Principais conclusões:
- A DI inverte a criação de dependências: o contêiner cria os objetos, não a própria classe
- Registre serviços com AddTransient / AddScoped / AddSingleton
- A injeção pelo construtor é a abordagem padrão e preferida
- Genéricos abertos, decoradores e ValidateOnBuild são recursos avançados poderosos
Aprenda C# com um tutor de IA — grátis
Escreva e execute código real no seu navegador, obtenha ajuda instantânea de um tutor de IA 24/7 e continue de onde parou na web ou no app.
- Cursos
- 93
- Aulas
- 346
Perguntas Frequentes
A aula “Fundamentos do contêiner de DI” é grátis?
Sim — o texto completo de “Fundamentos do contêiner de DI” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de C# Academy, atualize para CoddyKit PRO. O curso de C# Academy inclui 4 aulas no total.
O que vou aprender em “Fundamentos do contêiner de DI”?
Entenda a inversão de controle, o registro de serviços e como o contêiner de DI do .NET resolve dependências. Você pratica C# Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.
Preciso ter experiência prévia para começar C# Academy?
Nenhuma experiência prévia é necessária. C# Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 1 de 4.
Quanto tempo leva a aula “Fundamentos do contêiner de DI”?
A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.
Posso escrever e executar código nesta aula de C# Academy?
Sim. Cada aula de C# Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.
Todas as aulas deste curso
- Fundamentos do contêiner de DI
- Ciclos de vida dos serviços: Transient, Scoped e Singleton
- Injeção pelo construtor e interfaces
- Padrões Factory e Options