"A confusão começa quando diferentes áreas de negócio compartilham um mesmo modelo de dados." — Eric Evans
Com o crescimento de aplicações, principalmente em arquiteturas de microserviços, cresce também a complexidade de lidar com múltiplos domínios de negócio. É aí que entra o DDD (Domain-Driven Design) e seu conceito-chave: o Bounded Context.
Neste artigo, vamos explorar como aplicar DDD com Bounded Contexts na prática, utilizando .NET 8, organização de pastas e exemplos reais.
📦 O que é um Bounded Context?
Um Bounded Context é uma fronteira explícita dentro de um domínio, onde um modelo específico é definido e aplicado de forma consistente.
Na prática, isso significa separar funcionalidades como Financeiro
, Cadastro
, Logística
, etc., em contextos independentes — cada um com seu vocabulário, regras de negócio e estrutura de dados.
🧰 Tecnologias Utilizadas
- .NET 8 (Web API)
- Clean Architecture
- DDD tactical patterns (Entity, Aggregate, Repository, Service)
- MediatR (opcional)
- MongoDB/PostgreSQL (dependendo do contexto)
- EventBus (ex: RabbitMQ/Kafka para comunicação entre contextos)
🗂 Estrutura de Projeto com Bounded Contexts
src/
├── CatalogContext/
│ ├── Catalog.Application/
│ ├── Catalog.Domain/
│ ├── Catalog.Infrastructure/
│ └── Catalog.API/
│
├── SalesContext/
│ ├── Sales.Application/
│ ├── Sales.Domain/
│ ├── Sales.Infrastructure/
│ └── Sales.API/
│
└── BuildingBlocks/
├── EventBus/
├── Core/
└── Logging/
Cada contexto:
- É autônomo
- Possui seu próprio domínio e aplicação
- Expõe APIs próprias (REST ou gRPC)
- Se comunica com outros contextos via eventos, nunca diretamente
🧠 Exemplo Prático: Catálogo e Vendas
✅ Catálogo (CatalogContext)
Responsável por: gerenciamento de produtos, preços, estoque
Entidade Product
public class Product
{
public Guid Id { get; private set; }
public string Name { get; private set; }
public decimal Price { get; private set; }
public Product(string name, decimal price)
{
Id = Guid.NewGuid();
Name = name;
Price = price;
}
public void UpdatePrice(decimal newPrice)
{
if (newPrice <= 0)
throw new DomainException("Preço inválido.");
Price = newPrice;
}
}
🛒 Vendas (SalesContext)
Responsável por: criação de pedidos, status de pagamento
Comando CreateOrderCommand
public class CreateOrderCommand : IRequest<Guid>
{
public Guid ProductId { get; set; }
public int Quantity { get; set; }
}
Handler usando MediatR
public class CreateOrderHandler : IRequestHandler<CreateOrderCommand, Guid>
{
private readonly IOrderRepository _orderRepo;
public async Task<Guid> Handle(CreateOrderCommand request, CancellationToken cancellationToken)
{
var order = new Order(request.ProductId, request.Quantity);
await _orderRepo.AddAsync(order);
return order.Id;
}
}
🔗 Comunicação entre Contextos
Como SalesContext
não tem acesso direto a Product
, ele escuta um evento de domínio disparado por CatalogContext
:
// Evento no Catalog.Domain
public class ProductPriceChangedEvent : IntegrationEvent
{
public Guid ProductId { get; set; }
public decimal NewPrice { get; set; }
}
Em SalesContext
, um handler consome esse evento e atualiza caches ou triggers de revalidação de pedidos.
🧭 Vantagens dos Bounded Contexts
✅ Redução de acoplamento
✅ Modelagem centrada no negócio
✅ Escalabilidade por domínio
✅ Facilidade para times independentes
✅ Base para adoção de microsserviços
🚨 Cuidados ao Aplicar
⚠️ Evite contextos genéricos (ex: “Core” com tudo misturado)
⚠️ Não compartilhe entidades entre contextos
⚠️ Prefira comunicação eventual/assíncrona
🧩 Quando aplicar Bounded Contexts?
Situação | Recomendado? |
---|---|
Módulos com lógicas distintas | ✅ Sim |
Times atuando em áreas separadas | ✅ Sim |
Microsserviços ou monólitos modulares | ✅ Sim |
CRUD simples e pequeno | ❌ Overkill |
🧪 Próximos passos
Se quiser evoluir esse projeto, você pode:
- Adicionar EventBus para comunicação (Kafka, RabbitMQ, etc.)
- Usar OpenTelemetry para rastrear eventos entre contextos
- Aplicar testes de contrato e integração assíncrona
🤝 Conecte-se Comigo
Se você também está aplicando DDD, arquitetura em camadas ou quer debater cenários reais, vamos trocar ideias:
- 💻 Dev.to
- ✍️ Medium
- 📬 [email protected]
Top comments (0)
Some comments may only be visible to logged-in visitors. Sign in to view all comments.