DEV Community

Cover image for Comunicação Entre a Camada de Domínio e a Camada de Infraestrutura no .NET
Danilo O. Pinheiro, dopme.io
Danilo O. Pinheiro, dopme.io

Posted on

Comunicação Entre a Camada de Domínio e a Camada de Infraestrutura no .NET

Em uma arquitetura limpa e escalável, cada camada da aplicação possui uma responsabilidade clara. A camada de domínio foca nas regras de negócio, enquanto a camada de infraestrutura lida com preocupações externas (bancos de dados, APIs, sistemas de arquivos, mensageria, etc).

Mas como essas duas camadas podem se comunicar de forma eficaz sem quebrar o Princípio da Inversão de Dependência e mantendo uma arquitetura desacoplada?

Vamos explorar isso em detalhes.


🎯 Objetivo de Cada Camada

Camada Responsabilidade
Domínio Lógica de negócio, regras, entidades, value objects, agregados
Infraestrutura Acesso a dados, serviços de terceiros, mensageria, etc.

🔄 Direção das Dependências

Para seguir os princípios da Clean Architecture ou Arquitetura Hexagonal (Ports and Adapters), as dependências sempre devem apontar para dentro, ou seja, das camadas externas para as internas.

Isso significa:

  • A camada de domínio NÃO deve depender da infraestrutura.
  • A camada de infraestrutura deve depender das abstrações do domínio.

Essa separação é viabilizada por meio de interfaces definidas no domínio, com implementações fornecidas pela infraestrutura.


🛠️ Passo a Passo da Implementação

1. ✅ Defina uma Interface no Domínio

// Domain/Interfaces/IEmailSender.cs
namespace Domain.Interfaces;

public interface IEmailSender
{
    Task SendEmailAsync(string to, string subject, string body);
}
Enter fullscreen mode Exit fullscreen mode

2. 🧱 Implemente a Interface na Infraestrutura

// Infrastructure/Services/EmailSender.cs
using Domain.Interfaces;

public class EmailSender : IEmailSender
{
    public async Task SendEmailAsync(string to, string subject, string body)
    {
        // Lógica de envio de e-mail (SMTP, SendGrid, etc.)
    }
}
Enter fullscreen mode Exit fullscreen mode

3. 🧩 Registre a Implementação na Injeção de Dependência

// No Startup.cs ou Program.cs
services.AddScoped<IEmailSender, EmailSender>();
Enter fullscreen mode Exit fullscreen mode

Agora, qualquer serviço, caso de uso ou lógica de aplicação pode depender de IEmailSender sem saber como o envio de e-mail é feito.


🧠 Por Que Esse Padrão é Importante

✅ Separação de Responsabilidades

O domínio não precisa saber como a infraestrutura funciona. Ele apenas sabe o que precisa.

✅ Testabilidade

Você pode mockar as interfaces para testar a lógica de negócio sem precisar de banco de dados, APIs reais, etc.

✅ Manutenção

Você pode alterar a infraestrutura (ex: trocar SMTP por SendGrid) sem alterar nenhuma linha do código de domínio.


🧪 Caso de Uso Real: Padrão de Repositório

Interface no Domínio

public interface ICustomerRepository
{
    Task<Customer?> GetByIdAsync(Guid id);
    Task AddAsync(Customer customer);
}
Enter fullscreen mode Exit fullscreen mode

Implementação na Infraestrutura

public class CustomerRepository : ICustomerRepository
{
    private readonly AppDbContext _context;

    public CustomerRepository(AppDbContext context)
    {
        _context = context;
    }

    public async Task<Customer?> GetByIdAsync(Guid id)
    {
        return await _context.Customers.FindAsync(id);
    }

    public async Task AddAsync(Customer customer)
    {
        await _context.Customers.AddAsync(customer);
        await _context.SaveChangesAsync();
    }
}
Enter fullscreen mode Exit fullscreen mode

📌 Recomendações

  • Crie interfaces para todas as dependências que a camada de domínio necessita.
  • Agrupe interfaces em Domain.Interfaces ou Domain.Contracts.
  • Evite referenciar DbContext, bibliotecas externas ou qualquer código específico de infraestrutura dentro do domínio.
  • As implementações podem usar EF Core, Dapper, Polly, Refit, etc., desde que estejam na infraestrutura.

🧭 Ferramentas e Padrões Úteis

  • Injeção de Dependência (nativa no ASP.NET Core)
  • Evite o Anti-padrão Service Locator
  • Princípios SOLID (especialmente DIP e ISP)
  • Unit of Work / Repository Pattern (com moderação)
  • Mediator (MediatR) – para desacoplamento de handlers

✅ Conclusão

A comunicação entre a camada de domínio e a infraestrutura no .NET deve respeitar os limites de abstração. O domínio define o que deve ser feito, e a infraestrutura define como isso será realizado.

Com o uso de interfaces e injeção de dependência, você mantém sua arquitetura limpa, flexível e testável.


🤝 Conecte-se Comigo

Se você trabalha com .NET moderno e quer dominar arquitetura, C#, DevOps ou interoperabilidade, vamos conversar:

Top comments (0)