Conceito e fluxo de dependências
ResumoA Onion Architecture organiza o sistema em camadas concêntricas onde as dependências apontam sempre para dentro, em direção ao domínio. Isso mantém as regras de negócio independentes de banco, framework e UI.
1. Objetivos de Aprendizagem#
- Descrever as camadas da Onion Architecture e sua responsabilidade.
- Explicar a regra do fluxo de dependências (para dentro).
- Relacionar Onion com o princípio de Inversão de Dependência (SOLID).
2. Pré-requisitos#
- Serviço de logging desacoplado por interface (Módulo 16).
3. Conceito#
Camadas, do centro para fora:
- Domain (Entities) — entidades e regras de negócio puras. Nenhuma dependência externa.
- Contracts / Service Abstractions — interfaces (
IRepository,IService). - Service Layer — orquestra regras de negócio, mapeia DTOs.
- Infrastructure — EF Core, acesso a dados, provedores externos.
- Presentation (API) — controllers, o mundo HTTP.
A regra central: código de dentro nunca conhece código de fora. O domínio não referencia EF Core; quem referencia infraestrutura é a camada externa. Isso é o Dependency Inversion Principle: dependa de abstrações, não de implementações.
4. Mão na Massa#
4.1. Setup#
Crie os projetos que representam as camadas:
dotnet new classlib -n Catalog.Entities -f net9.0
dotnet new classlib -n Catalog.Contracts -f net9.0 # (já criado no Módulo 16)
dotnet new classlib -n Catalog.Service.Contracts -f net9.0
dotnet new classlib -n Catalog.Service -f net9.0
dotnet new classlib -n Catalog.Repository -f net9.0
dotnet sln add Catalog.Entities Catalog.Service.Contracts Catalog.Service Catalog.Repository
4.2. Implementação Passo a Passo#
- Configure as referências respeitando o fluxo para dentro:
dotnet add Catalog.Contracts reference Catalog.Entities
dotnet add Catalog.Repository reference Catalog.Contracts Catalog.Entities
dotnet add Catalog.Service.Contracts reference Catalog.Entities
dotnet add Catalog.Service reference Catalog.Service.Contracts Catalog.Contracts Catalog.Entities
dotnet add Catalog.Api reference Catalog.Service Catalog.Repository
- Note que
Catalog.Entitiesnão referencia ninguém — é o núcleo.
4.3. Executando#
dotnet build
O build valida que não há referências circulares nem dependências apontando para fora.
5. Exemplo Completo#
Grafo de dependências (texto):
Catalog.Api → Catalog.Service, Catalog.Repository
Catalog.Service → Catalog.Service.Contracts, Catalog.Contracts, Catalog.Entities
Catalog.Repository → Catalog.Contracts, Catalog.Entities
Catalog.Contracts → Catalog.Entities
Catalog.Entities → (nada)
6. Boas Práticas e Armadilhas#
| Faça | Evite |
|---|---|
| Manter o domínio livre de dependências de infraestrutura | Referenciar EF Core dentro de Catalog.Entities |
| Definir interfaces na camada interna, implementá-las na externa | Fazer o serviço depender diretamente do DbContext |
| Adotar a arquitetura de forma proporcional ao projeto | Impor 6 projetos numa API CRUD trivial |
AtençãoOnion não é bala de prata. Para uma API pequena, tanta cerimônia pode ser overengineering. Use o nível de separação que o projeto realmente exige.
7. Segurança e Produção#
- A separação em camadas facilita aplicar autorização na camada de apresentação e validação de regras na camada de serviço, sem misturar responsabilidades.
8. Exercícios#
- Fácil: desenhe o diagrama de dependências do seu próprio projeto.
- Médio: explique por que colocar o
DbContextno domínio quebra a arquitetura. - Desafio: liste tradeoffs entre Onion e uma arquitetura em camadas tradicional (N-tier) para uma equipe pequena.
9. Resumo#
Onion Architecture organiza o sistema em camadas concêntricas com dependências apontando para dentro. O domínio é o núcleo estável; infraestrutura e apresentação são detalhes substituíveis.
10. Próximos Passos#
A seguir criamos as entidades, o DbContext e as migrations do EF Core.
11. Referências#
- Microsoft Learn — Arquiteturas de aplicações web comuns
- Microsoft Learn — Princípios de arquitetura
- Microsoft Learn — Entity Framework Core