O ganho real está nas fronteiras
O valor da clean architecture está em separar o que é regra de negócio do que é banco, framework, API ou interface. Isso reduz acoplamento, facilita teste e torna a evolução mais previsível em sistemas corporativos longos.
Onde ela costuma falhar
O problema aparece quando o time replica interface, caso de uso e camada abstrata para cenários em que a complexidade ainda não justifica isso. A arquitetura precisa servir ao sistema, não o contrário.
- Modele apenas as fronteiras que o domínio precisa
- Evite abstração por reflexo
- Use nomes claros e responsabilidade objetiva
- Adoção gradual costuma ser mais segura que reestruturação total
Modernizando sistemas .NET?
Veja como a ArrexTec ajuda empresas nessa situação — sem reescrever tudo do zero.
Ver serviço de arquitetura .NETComo adotar sem parar a operação
O caminho mais seguro é reorganizar pontos do sistema onde regra de negócio já está misturada demais com integração e persistência. Aos poucos, a base passa a sustentar melhor testes, mudanças e novas demandas.
A única regra que realmente importa
Clean Architecture costuma ser apresentada como um diagrama de círculos concêntricos, e é aí que a maioria das implementações se perde — o time copia os círculos e ignora o princípio. A regra que sustenta tudo é uma só: as dependências apontam sempre para dentro.
O domínio não conhece o banco. O caso de uso não conhece o controller. Se a sua entidade tem um atributo do Entity Framework, ou se a regra de negócio importa Microsoft.AspNetCore, a seta inverteu e o benefício evaporou — não importa quantas pastas com nomes certos existam no projeto.
Numa solução .NET isso se traduz em quatro projetos com referências em uma direção só:
- Domain — entidades e regras. Não referencia nada.
- Application — casos de uso e as interfaces do que ele precisa (
IPedidoRepository,INotificador). Referencia só o Domain. - Infrastructure — EF Core, HTTP, fila, e-mail. Implementa as interfaces da Application e referencia ela.
- Api / Web — controllers e composição. Referencia Application e, só na inicialização, Infrastructure.
O teste é mecânico: se você conseguir remover a referência do Domain a qualquer pacote de infraestrutura e o projeto continuar compilando, a arquitetura está de pé. Se não compilar, o diagrama é decoração.
O erro mais caro: repositório em cima do EF Core
É o padrão que mais aparece em código corporativo .NET e o que mais gera trabalho sem retorno: envolver o Entity Framework em uma camada de repositórios e Unit of Work.
O problema é que o DbContext já é um Unit of Work e o DbSet já é um repositório. Recriar isso por cima costuma produzir uma interface com trinta métodos ObterPorX, ou — pior — um repositório que devolve IQueryable e vaza a semântica do ORM para todas as camadas, exatamente o acoplamento que se queria evitar.
A justificativa clássica é "para poder trocar de banco". Isso quase nunca acontece, e quando acontece a camada de repositório não é o que salva. A justificativa boa é outra: isolar a Application de detalhes de persistência para poder testar caso de uso sem banco. Para isso, a interface deve falar a linguagem do domínio — `ObterPedidosPendentesDoCliente` — e não expor consulta genérica.
Quando a consulta é só leitura para uma tela, vale pular a cerimônia e consultar direto. Separar leitura de escrita resolve isso de forma mais honesta, e é o assunto de CQRS na prática em sistemas .NET.
O que você ganha na prática: testes sem infraestrutura
O benefício mais concreto da separação aparece na suíte de testes. Com as dependências invertidas, o teste de um caso de uso não precisa de banco, de fila nem de container subindo.
Isso muda o número que importa: uma suíte que roda em segundos é executada a cada alteração; uma que leva vinte minutos é executada na véspera do deploy, quando o erro já custa caro. É a diferença entre ter rede de segurança e ter relatório de acidente.
Em sistemas corporativos com regra de negócio densa — cálculo de comissão, regra fiscal, política de crédito — esse ganho se paga rápido. É justamente onde o custo de um erro em produção é maior e onde testar pela interface é mais lento e mais frágil.
Quando Clean Architecture é excesso
A separação em quatro projetos, interfaces e casos de uso tem custo: mais arquivos, mais indireção, mais tempo para um desenvolvedor novo entender o caminho de uma requisição. Esse custo se justifica quando existe regra de negócio real para proteger.
Não se justifica quando:
- O sistema é essencialmente CRUD — se a "regra" é validar campo obrigatório e gravar, a camada de domínio fica vazia e você criou cerimônia sem conteúdo.
- É um serviço pequeno e estável — integração que traduz um formato para outro não precisa de quatro projetos.
- O time não tem experiência com o padrão — Clean Architecture mal aplicada é pior que camada única bem organizada, porque adiciona indireção sem entregar isolamento.
O critério é o mesmo de sempre: a arquitetura serve ao sistema, não o contrário. Complexidade acidental adicionada "por boa prática" é dívida técnica com nome bonito.
Como migrar um sistema existente
Reestruturar tudo de uma vez é o caminho mais rápido para um projeto de seis meses sem entrega. A abordagem que funciona é por fatia vertical, começando pelo caso de uso que mais dói:
- 1. Escolha uma funcionalidade com regra de negócio relevante e que mude com frequência.
- 2. Cubra o comportamento atual com testes antes de mover qualquer linha.
- 3. Extraia a regra para uma classe sem dependência de infraestrutura.
- 4. Crie a interface do que ela precisa e implemente na camada de infraestrutura existente.
- 5. Repita na próxima funcionalidade.
O código antigo continua funcionando ao lado do novo o tempo todo. A mecânica dessa convivência está detalhada em refatoração progressiva em .NET.
Perguntas frequentes
Clean Architecture serve para qualquer sistema?
Não. Ela se paga quando existe regra de negócio relevante para isolar e o sistema tem vida longa. Para CRUD simples, serviço pequeno ou integração de tradução de formato, a separação em camadas adiciona indireção sem entregar benefício proporcional.
Qual a diferença entre Clean Architecture e DDD?
São coisas complementares em níveis diferentes. Clean Architecture organiza dependências entre camadas — é estrutural. DDD trata de como modelar o domínio: linguagem ubíqua, agregados, contextos delimitados. Dá para usar Clean Architecture com um domínio anêmico, e é justamente o que acontece quando se copia a estrutura sem modelar o negócio.
Preciso de repositório se já uso Entity Framework?
Nem sempre. O DbContext já cumpre o papel de Unit of Work e o DbSet o de repositório. A abstração se justifica quando você quer testar caso de uso sem banco e a interface fala a linguagem do domínio. Repositório genérico que devolve IQueryable só adiciona camada sem isolar nada.
Como saber se a arquitetura está sendo respeitada?
Pelo grafo de referências entre projetos, não por revisão de código. Se o Domain não referencia nada de infraestrutura e a Application não conhece a Api, a regra está de pé. Testes de arquitetura automatizados — com NetArchTest ou ArchUnitNET — falham o build quando alguém inverte uma seta, o que é mais confiável que disciplina.
Vale a pena migrar um sistema legado para Clean Architecture?
Vale se o sistema ainda vai viver anos e a regra de negócio muda com frequência. E migre por fatia vertical, nunca de uma vez: escolha um caso de uso, cubra com teste, extraia a regra, repita. Reestruturação total costuma virar projeto sem entrega intermediária.