Introdução
Seu principal objetivo é enfrentar os desafios encontrados na arquitetura em camadas e fornecer soluções para problemas comuns como aclopamento, separação das responsabilidades, colocando a regra de negócio no centro do sistema, isolando-as de detalhes como (banco de dados, interface, frameworks, etc.).
Descomplicando a Arquitetura
Na arquitetura em camadas tradicional, o fluxo de dependência é costuma a ser de fora pra dentro: a camada de interface (UI) interage com a lógica de negócio, que por sua vez depende da camada de dados. Esse modelo cria acoplamento direto entre as camadas, dificultando a substituição de tecnologias ou a realização de testes isolados.
A Onion Architecture propõe o inverso dessa lógica. Em vez de organizar o sistema a partir das camadas externas, ela o estrutura de dentro pra fora, tendo núcleo do domínio como centro.
As camadas internas contêm as regras de negócios puras e não conhecem nada sobre a infraestrutura ou interface. Já as camadas mais externas dependem das internas, atuando apenas como meios de entrada (UI, APIs) ou implementação de detalhes como banco de dados e/ou serviços externos.
Destrinchando as camadas
1. Camada de domínio (Domain Model)
Representa os objetos de negócios e o comportamento, e, pode conter interfaces de domínio.
- Essa camada não possui nenhuma dependência
2. Camada de serviço do Domínio (Domain Services)
Cria a abstração entre as entidades do domínio e a lógica dos negócios do aplicativo. Nesta camada, temos as interfaces que fornecem o comportamento de salvar e recuperar objetos, geralmente envolvendo um repositório que acessa a fonte de dados
4. Camada de serviço da Aplicação (Application Services)
A camada da aplicação que mantém interfaces com operaçÕes comuns como adicionar, salvar, editar e excluir. Além disso, essa camada é usada pra se comunicar com a camada de interface do usuário e da camada do repositório.
- É nessa camada que acessamos o “miolo” do projeto.
5. Camada externas (UI, Infrastructure, tests)
É o anel mais externo da arquitetura. Nele temos os componentes que mudam com frequência: a camada de apresentação, o acesso aos dados e os testes
Exemplo de Projeto
Example/ │ ├── Core/ │ ├── Domain/ │ │ ├── Entities/ │ │ │ ├── UserEntity.cs │ │ │ └── GroupEntity.cs │ │ ├── Dependencies/ │ │ └── Exceptions/ ← (opcional) │ │ │ ├── DomainServices/ │ │ ├── Repositories/ │ │ │ ├── IUserRepository.cs │ │ │ └── IGroupRepository.cs │ │ ├── Dependencies/ │ │ └── Validators/ ← (opcional) │ │ │ └── Application/ │ ├── Services/ │ │ ├── IUserService.cs │ │ ├── IGroupService.cs │ │ ├── UserService.cs │ │ └── GroupService.cs │ ├── DTOs/ ← (opcional) │ ├── Mappers/ ← (opcional) │ └── Dependencies/ │ ├── Infrastructure/ │ ├── Repositories/ │ │ ├── UserRepository.cs │ │ └── GroupRepository.cs │ ├── Data/ │ │ ├── AppDbContext.cs │ │ └── Configurations/ │ ├── Dependencies/ │ └── Migrations/ ← (caso use EF Core) │ └── WebApi/ ├── Controllers/ │ ├── UserController.cs │ └── GroupController.cs ├── Program.cs ├── Startup.cs └── appsettings.json | Camada da Cebola | Pasta no projeto | Responsabilidade principal |
|---|---|---|
| Domain | Example.Core.Domain | Entidades e regras de negócio puras |
| Domain Services | Example.Core.DomainServices | Interfaces de repositórios e regras de domínio mais complexas |
| Application | Example.Core.Application | Casos de uso, orquestração e serviços de aplicação |
| Infrastructure | Example.Infrastructure | Implementações concretas (banco, API externa etc.) |
| UI / API | Example.WebApi | Ponto de entrada da aplicação (controladores REST, endpoints) |
Exemplo simples: “Cadastrar Usuário”
Parafraseando o ChatGPT temos o seguinte cenário:
1️⃣ Camada mais externa – WebAPI (Interface / Delivery Layer)
É o ponto de entrada — recebe a requisição HTTP.
// Example.WebApi.Controllers/UserController.cs [ApiController] [Route("api/users")] public class UserController : ControllerBase { private readonly IUserService _userService; public UserController(IUserService userService) { _userService = userService; } [HttpPost] public IActionResult Create(UserDto user) { _userService.CreateUser(user); return Ok(); } } 📤 Fluxo:
➡️ WebApi chama Application
A API não conhece o domínio nem o banco — só o serviço da aplicação.
2️⃣ Camada de Aplicação (Application Layer)
Contém regras de orquestração, casos de uso, DTOs e interfaces de serviço.
// Example.Core.Application.Services/UserService.cs public class UserService : IUserService { private readonly IUserRepository _userRepository; private readonly IPasswordHasher _passwordHasher; public UserService(IUserRepository userRepository, IPasswordHasher passwordHasher) { _userRepository = userRepository; _passwordHasher = passwordHasher; } public void CreateUser(UserDto user) { var entity = new UserEntity(user.Name, _passwordHasher.Hash(user.Password)); _userRepository.Save(entity); } } 📤 Fluxo:
➡️ Application chama Domain (para criar entidades)
➡️ Application chama Infrastructure (através da interface IUserRepository)
3️⃣ Camada de Domínio (Domain Layer)
É o núcleo da cebola, contendo regras de negócio puras, entidades e interfaces.
// Example.Core.Domain/Entities/UserEntity.cs public class UserEntity { public string Name { get; } public string PasswordHash { get; } public UserEntity(string name, string passwordHash) { if (string.IsNullOrEmpty(name)) throw new ArgumentException("Nome é obrigatório"); Name = name; PasswordHash = passwordHash; } } 📤 Fluxo:
➡️ Domain é chamado por Application, mas não depende de ninguém.
4️⃣ Camada de Infraestrutura (Infrastructure Layer)
Implementa interfaces definidas no domínio — banco, APIs externas, etc.
// Example.Infrastructure.Repositories/UserRepository.cs public class UserRepository : IUserRepository { private readonly AppDbContext _context; public UserRepository(AppDbContext context) { _context = context; } public void Save(UserEntity user) { _context.Users.Add(user); _context.SaveChanges(); } } 📤 Fluxo:
➡️ Infrastructure é chamada por Application, mas depende do Domain (pelas interfaces e entidades).
🔁 Fluxo geral do “Cadastrar Usuário”:
| Ordem | Ação | De | Para |
|---|---|---|---|
| 1 | Requisição HTTP POST | 🧩 WebApi | Application |
| 2 | Executa caso de uso | Application | Domain (cria UserEntity) |
| 3 | Persiste usuário | Application | Infrastructure (UserRepository) |
| 4 | Repositório salva no banco | Infrastructure | Banco de dados |

Top comments (0)