DEV Community

Domain-Driven Design com .NET

Domain-Driven Design (DDD) é uma abordagem arquitetural que coloca o foco no núcleo do negócio. Ela propõe modelar o software com base em regras de negócio reais, usando uma linguagem comum entre devs e especialistas. Em sistemas .NET, essa abordagem é perfeitamente compatível com padrões como Clean Architecture, CQRS, e o uso de ferramentas modernas como Entity Framework, MediatR e ASP.NET Core.


🧠 Princípios-Chave do DDD

Conceito Definição
Domínio Área central do problema que o sistema resolve
Modelo de Domínio Representação do conhecimento do domínio em código
Entidade Objeto com identidade única (ex: Cliente, Pedido)
Value Object Objeto imutável sem identidade, definido por seus valores (ex: CPF)
Aggregate Conjunto de entidades e VOs com regras de consistência
Root Aggregate Entidade raiz que gerencia o agregado
Repository Interface para persistência de agregados
Bounded Context Fronteira lógica onde o modelo é consistente
Linguagem Ubíqua Vocabulário comum entre devs e especialistas

🏗️ Estrutura de Projeto Sugerida

src/ ├── Domain/ ├── Application/ ├── Infrastructure/ └── WebAPI/ 
Enter fullscreen mode Exit fullscreen mode

🔧 Exemplo Prático: Sistema de Pedidos

Entidade Pedido

public class Pedido { public Guid Id { get; private set; } public DateTime CriadoEm { get; private set; } private readonly List<ItemPedido> _itens; public IReadOnlyCollection<ItemPedido> Itens => _itens; public Pedido() { Id = Guid.NewGuid(); CriadoEm = DateTime.UtcNow; _itens = new List<ItemPedido>(); } public void AdicionarItem(string produto, decimal preco, int quantidade) { if (string.IsNullOrWhiteSpace(produto)) throw new DomainException("Produto inválido."); _itens.Add(new ItemPedido(produto, preco, quantidade)); } public decimal ObterTotal() => _itens.Sum(i => i.Total()); } 
Enter fullscreen mode Exit fullscreen mode

Value Object: ItemPedido

public class ItemPedido { public string Produto { get; } public decimal PrecoUnitario { get; } public int Quantidade { get; } public ItemPedido(string produto, decimal preco, int quantidade) { Produto = produto; PrecoUnitario = preco; Quantidade = quantidade; } public decimal Total() => PrecoUnitario * Quantidade; } 
Enter fullscreen mode Exit fullscreen mode

🔌 Repositório + EF Core

public interface IPedidoRepository { Task<Pedido> ObterPorIdAsync(Guid id); Task AdicionarAsync(Pedido pedido); } 
Enter fullscreen mode Exit fullscreen mode
public class PedidoRepository : IPedidoRepository { private readonly DbContext _context; public PedidoRepository(DbContext context) => _context = context; public async Task<Pedido> ObterPorIdAsync(Guid id) => await _context.Set<Pedido>().FindAsync(id); public async Task AdicionarAsync(Pedido pedido) { await _context.Set<Pedido>().AddAsync(pedido); await _context.SaveChangesAsync(); } } 
Enter fullscreen mode Exit fullscreen mode

🚀 Aplicando CQRS com MediatR

Comando

public record CriarPedidoCommand(List<ItemDTO> Itens) : IRequest<Guid>; 
Enter fullscreen mode Exit fullscreen mode

Handler

public class CriarPedidoHandler : IRequestHandler<CriarPedidoCommand, Guid> { private readonly IPedidoRepository _pedidoRepository; public CriarPedidoHandler(IPedidoRepository repo) => _pedidoRepository = repo; public async Task<Guid> Handle(CriarPedidoCommand request, CancellationToken cancellationToken) { var pedido = new Pedido(); foreach (var item in request.Itens) pedido.AdicionarItem(item.Produto, item.Preco, item.Quantidade); await _pedidoRepository.AdicionarAsync(pedido); return pedido.Id; } } 
Enter fullscreen mode Exit fullscreen mode

✅ Boas Práticas

  • Modele a linguagem do negócio antes de começar a codar.
  • Use DDD somente onde há complexidade de domínio.
  • Mantenha regras dentro das entidades, evitando serviços anêmicos.
  • Evite acoplamentos entre Bounded Contexts diretamente.
  • Utilize testes unitários focando no comportamento do domínio.

📦 Ferramentas Úteis no Ecossistema .NET + DDD

Ferramenta Finalidade
Entity Framework Core ORM e persistência
MediatR Implementação de CQRS
AutoMapper Conversão entre modelos e DTOs
FluentValidation Validação de entrada
Serilog Logging estruturado
Swashbuckle/Swagger Documentação automática da API

📘 Conclusão

DDD é uma abordagem que dá estrutura e clareza ao desenvolvimento de sistemas complexos. Em vez de focar apenas em tecnologia, ele prioriza o negócio, as regras e a linguagem da empresa. No ecossistema .NET, temos suporte maduro para aplicar os padrões recomendados e escalar sistemas com qualidade e robustez.


🤝 Conecte-se Comigo

Top comments (0)