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)