Aprenda Injeção de Dependência com C# 13 em 90 Minutos

A injeção de dependênciaGenética do vício: por que algumas pessoas ficam viciadas mais facilmente?Genética do vício: por que algumas pessoas ficam viciadas mais facilmente?Descubra como a genética pode influenciar o vício e entenda como fatores biológicos e ambientais se combinam na dependência. (ID) é uma prática fundamental que visa desacoplar componentes do seu sistema, facilitando testes, manutenção e extensões futuras. No C# 13, manter uma arquitetura limpaCombinando C# 13 com Design Patterns para arquitetura limpaCombinando C# 13 com Design Patterns para arquitetura limpaExplore neste tutorial como as inovações do C# 13 aprimoram Design Patterns e arquiteturas limpas. Aprenda com exemplos práticos em 90 min. e organizada torna-se ainda mais simples graças às melhorias de sintaxe e novas funcionalidades que ajudam na clareza do código. Nesta narrativa, exploraremos como configurar essa técnica, demonstrar exemplos de uso e apresentar boas práticas relacionadas a contêineres de injeção de dependência para que você possa ter um código mais confiável e flexível.

Por que usar Injeção de Dependência?🔗

Em termos de design de software, a injeção de dependênciaGenética do vício: por que algumas pessoas ficam viciadas mais facilmente?Genética do vício: por que algumas pessoas ficam viciadas mais facilmente?Descubra como a genética pode influenciar o vício e entenda como fatores biológicos e ambientais se combinam na dependência. atende ao Princípio da Inversão de DependênciaGenética do vício: por que algumas pessoas ficam viciadas mais facilmente?Genética do vício: por que algumas pessoas ficam viciadas mais facilmente?Descubra como a genética pode influenciar o vício e entenda como fatores biológicos e ambientais se combinam na dependência. (D do SOLID). Em resumo, em vez de uma classe instanciar diretamente suas dependências (por exemplo, new ClasseX()), essas dependências são entregues (ou injetadas) a ela, normalmente em seu construtor. Isso promove:

Quando empregado junto a contêineres de injeção (chamados IoC containers), a configuração fica ainda mais ágil e poderosa.

Estrutura Básica de uma Injeção de Dependência🔗

No C# 13O que é C# 13 e por que aprender em 90 minutosO que é C# 13 e por que aprender em 90 minutosExplore as inovações do C# 13 e melhore a legibilidade do seu código. Este tutorial prático de 90 minutos oferece dicas essenciais para desenvolvedores .NET., integrando-se à abordagem .NET moderna, é comum utilizar a classe ServiceCollection para registrar dependências. Veja um exemplo de como você pode estruturar:

using Microsoft.Extensions.DependencyInjection;
public interface IEmailService
{
    void SendEmail(string address, string content);
}
public class SmtpEmailService : IEmailService
{
    public void SendEmail(string address, string content)
    {
        // Lógica de envio via SMTP
        Console.WriteLine($"Enviando e-mail para {address} via SMTP: {content}");
    }
}
class Program
{
    static void Main()
    {
        var services = new ServiceCollection();
        // Registrando dependências
        services.AddTransient<IEmailService, SmtpEmailService>();
        // Construindo o provedor de serviços
        var serviceProvider = services.BuildServiceProvider();
        // Resolvendo a dependência
        var emailService = serviceProvider.GetRequiredService<IEmailService>();
        emailService.SendEmail("[email protected]", "Olá! Esta é uma mensagem de teste.");
    }
}

No código acima:

1. Definimos uma interfaceTrabalhando com interfaces e coleções aprimoradas em C# 13Trabalhando com interfaces e coleções aprimoradas em C# 13Descubra como as implementações padrão em interfaces e coleções aprimoradas do C# 13 otimizam a criação de códigos modulares, seguros e performáticos. (IEmailService) que estabelece o contrato do serviço de envio de e-mails.

2. SmtpEmailService implementa essa interfaceTrabalhando com interfaces e coleções aprimoradas em C# 13Trabalhando com interfaces e coleções aprimoradas em C# 13Descubra como as implementações padrão em interfaces e coleções aprimoradas do C# 13 otimizam a criação de códigos modulares, seguros e performáticos..

3. Registramos a implementação usando AddTransient<IEmailService, SmtpEmailService>(). Isso sinaliza ao contêiner que, sempre que a aplicação solicitar um IEmailService, ele deve fornecer uma nova instância de SmtpEmailService.

4. Construímos (BuildServiceProvider()) e resolvemos (GetRequiredService<IEmailService>()) a dependênciaGenética do vício: por que algumas pessoas ficam viciadas mais facilmente?Genética do vício: por que algumas pessoas ficam viciadas mais facilmente?Descubra como a genética pode influenciar o vício e entenda como fatores biológicos e ambientais se combinam na dependência. para utilizá-la.

Comparando Ciclo de Vida das Dependências🔗

Um ponto crucial na injeção de dependênciaGenética do vício: por que algumas pessoas ficam viciadas mais facilmente?Genética do vício: por que algumas pessoas ficam viciadas mais facilmente?Descubra como a genética pode influenciar o vício e entenda como fatores biológicos e ambientais se combinam na dependência. é definir o ciclo de vida (lifetime) das instâncias. No C# 13, a sintaxe e métodos permanecem muito próximos das versões anteriores, porém ganharam maior clareza com recursos de null-checkingRecursos avançados de null-checking no C# 13Recursos avançados de null-checking no C# 13Aprenda a dominar o null-checking em C# 13 com técnicas avançadas e exemplos práticos que garantem código seguro, legível e performático. e correções de warnings que reforçam boas práticas. As três opções comuns de lifetimes são:

MétodoDescrição
AddTransientCria uma instância sempre que requisitada. Ideal para serviços sem estado (stateless).
AddScopedCria uma instância por escopo (ex.: cada requisição web). Útil para dados de sessão.
AddSingletonCria uma instância única por aplicação. Recomendado para serviços que mantêm estado global.

Usando Contêineres Externos🔗

Embora o Microsoft.Extensions.DependencyInjection seja poderoso e totalmente integrado ao .NET, é comum utilizar contêineres de terceiros para cenários mais complexos ou que exijam recursos avançados, como:

  • Autofac: oferece modules, lifetime scopes mais personalizáveis e maior suporte a interceptação.
  • StructureMap ou Ninject: soluções maduras, cada uma com particularidades.

Em projetos que requerem larga escalabilidade, a escolha do contêiner pode depender de preferências da equipe e requisitos do projeto. A boa notícia é que, do ponto de vista de C# 13O que é C# 13 e por que aprender em 90 minutosO que é C# 13 e por que aprender em 90 minutosExplore as inovações do C# 13 e melhore a legibilidade do seu código. Este tutorial prático de 90 minutos oferece dicas essenciais para desenvolvedores .NET., a adaptação costuma ser transparente, pois a forma de registrar e resolver dependências segue conceitos semelhantes.

Boas Práticas e Dicas de Desempenho🔗

1. Evite “service locator”

Não use contêiner como service locator. Sempre injete dependências por construtor ou, em último caso, use injeção de propriedade.

2. Registre apenas o necessário

Mantenha o cadastro de serviços coerente com a necessidade da aplicação. Multifuncionalidades supérfluas sobrecarregam o contêiner e complicam a manutenção.

3. Combine com Recursos do C# 13O que é C# 13 e por que aprender em 90 minutosO que é C# 13 e por que aprender em 90 minutosExplore as inovações do C# 13 e melhore a legibilidade do seu código. Este tutorial prático de 90 minutos oferece dicas essenciais para desenvolvedores .NET.

Use pattern matchingDesenvolvimento multiplataforma com .NET MAUI e C# 13Desenvolvimento multiplataforma com .NET MAUI e C# 13Explore as novidades do C# 13 e crie apps multiplataforma com .NET MAUI neste tutorial prático, otimizado para desempenho e legibilidade. para lidar com comportamentos distintos dentro de serviços injetados e aplique recursos avançados de null-check para evitar erros de referência nula.

4. Monitore desempenho

Contêineres modernos costumam ser rápidos, mas fique atento a resoluções de serviços feitas em laços extensos ou pontos críticos de performance.

5. Documente seus registros

Comentários e organização de startup code ajudam a equipe a entender como as dependências estão configuradas.

Exemplo de Injeção e Resolução em Múltiplas Camadas🔗

Suponha que exista uma camada de Repositório e um Serviço que a consome. Podemos visualizar as relações usando um diagrama mermaid:

flowchart LR A[Controller] --> B[Serviço] B --> C[Repositório] C --> D[Banco de Dados]

Imagine o código simplificado:

public interface IProdutoRepository
{
    Produto ObterProduto(int id);
}
public class ProdutoRepository : IProdutoRepository
{
    public Produto ObterProduto(int id)
    {
        // Busca ou simulação de busca de produto no banco
        return new Produto { Id = id, Nome = "Produto Teste" };
    }
}
public interface IProdutoService
{
    Produto BuscarProduto(int id);
}
public class ProdutoService : IProdutoService
{
    private readonly IProdutoRepository _produtoRepository;
    public ProdutoService(IProdutoRepository produtoRepository)
    {
        _produtoRepository = produtoRepository;
    }
    public Produto BuscarProduto(int id)
    {
        // Lógica adicional e validações
        return _produtoRepository.ObterProduto(id);
    }
}
// No ponto de configuração (ex.: Program.cs)
var services = new ServiceCollection();
services.AddScoped<IProdutoRepository, ProdutoRepository>();
services.AddScoped<IProdutoService, ProdutoService>();

Esse padrão torna o código organizado e segue as diretrizes de injeção de dependênciaGenética do vício: por que algumas pessoas ficam viciadas mais facilmente?Genética do vício: por que algumas pessoas ficam viciadas mais facilmente?Descubra como a genética pode influenciar o vício e entenda como fatores biológicos e ambientais se combinam na dependência.. No C# 13, usar registros ou classes parciais para representar dados pode otimizar ainda mais a legibilidade, porém sem mudar a estrutura essencial de injeção mostrada.

Conclusão🔗

Consolidar a prática de injeção de dependênciaGenética do vício: por que algumas pessoas ficam viciadas mais facilmente?Genética do vício: por que algumas pessoas ficam viciadas mais facilmente?Descubra como a genética pode influenciar o vício e entenda como fatores biológicos e ambientais se combinam na dependência. e utilização de contêineres no C# 13 é fundamental para garantir que sua aplicação se mantenha escalável, testável e coesa. A sintaxe simplificada da linguagem e os novos recursos de verificação de nulidade contribuem para a clareza do código, fortalecendo um dos pilares da arquitetura limpaCombinando C# 13 com Design Patterns para arquitetura limpaCombinando C# 13 com Design Patterns para arquitetura limpaExplore neste tutorial como as inovações do C# 13 aprimoram Design Patterns e arquiteturas limpas. Aprenda com exemplos práticos em 90 min.: o desacoplamento.

Com essas bases sólidas, você estará pronto para criar aplicações mais robustas e bem estruturadas em menos tempo. É um passo essencial para quem deseja dominar as novidades do C# 13O que é C# 13 e por que aprender em 90 minutosO que é C# 13 e por que aprender em 90 minutosExplore as inovações do C# 13 e melhore a legibilidade do seu código. Este tutorial prático de 90 minutos oferece dicas essenciais para desenvolvedores .NET. em 90 min e elevar a qualidade do código a um novo patamar de legibilidade e desempenho.

Autor: Marcelo V. Souza - Engenheiro de Sistemas e Entusiasta em IoT e Desenvolvimento de Software, com foco em inovação tecnológica.

Referências🔗

Compartilhar artigo

Artigos Relacionados