ASP .NET Core - Clean Architecture


Hoje vamos apresentar o conceito de Clean Architecture e criar uma solução ASP .NET Core usando este conceito proposto por Uncle Bob no seu livro Clean Architecture.

O conceito de Arquitetura Limpa é baseado na Regra de Dependência, que afirma que a dependência do código-fonte só pode apontar para o interior do aplicativo.

As duas figuras abaixo traduzem o que isso quer dizer:

O Core da aplicação ou Application Core (casos de uso e entidades) contém as regras de negócios de alto nível do software que geralmente são estáveis e não mudam com frequência. Normalmente, esses são os requisitos funcionais do aplicativo.

Por exemplo, um aplicativo para uma loja online (bem simplificado) pode ter os seguintes casos de uso e entidades:

// Casos de uso:
public class AdicionarProdutoNoCarrinhoPeloCliente 
{
  public AdicionarProdutoNoCarrinhoPeloCliente(Produtos produto) {}
}
public class AdicionarProdutoAoInventarioPeloAdmin 
{
  public AdicionarProdutoAoInventarioPeloAdmin(Produtos produto) {}
}
// Entidades:

public class Clientes() 
{
  public int ClienteId { get; set; }
  public string ClienteNome { get; set; }
}

public class Produtos() 
{
  public int ProdutoId { get; set; }
  public string ProdutoNome { get; set; }
}
public class Pedidos() 
{
  public int PedidoId { get; set; }
  public int ClienteId { get; set; }
  public DateTime DateCriacao { get; set; }
}

Nota: Para simplificar estou apresentando as entidades sem comportamentos e totalmente anêmicas

Os casos de uso podem ser interfaces ou serviços, enquanto as entidades geralmente são classes de modelo de negócios que são persistentes.

As camadas da Arquitetura Limpa

De acordo com a documentação da ASP.Net Core, o nosso código-fonte pode ser estruturado como projetos separados ou camadas com fluxo de dependência de fora para a camada de núcleo do aplicativo.

O fluxo de dependência pode ser representado como mostra a figura :

De onde podemos depreender o seguinte:

  1. Os tipos Core do aplicativo incluem interfaces, serviços, DTO (objetos de transferência de dados) e entidades (modelos de negócios);
     
  2. Os tipos de Infraestrutura incluem tipos EF Core (DbContext, Migration), tipos de implementação de acesso a dados (Repositórios), Serviços específicos de infraestrutura (por exemplo, FileLogger ou SmtpNotifier);
     
  3. Os tipos de Interface do usuário incluem controladores, filtros, visualizações, modelos de visualização, inicialização;
     
  4. Os tipos de Testes incluem testes de unidade, testes de integração;

Observe que as setas sólidas representam dependências de tempo de compilação, enquanto a seta tracejada representa uma dependência apenas de tempo de execução.

Com a arquitetura limpa, a camada de IU funciona com interfaces definidas no Application Core no momento da compilação e, idealmente, não deve saber sobre os tipos de implementação definidos na camada de infraestrutura.

Em tempo de execução, no entanto, esses tipos de implementação são necessários para que o aplicativo seja executado, portanto, eles precisam estar presentes e conectados às interfaces do Application Core por meio de injeção de dependência.

A figura a seguir mostra uma visão mais detalhada da arquitetura de um aplicativo ASP.NET Core quando construído seguindo essas recomendações:

Vamos então criar uma solução ASP .NET Core usando o Visual Studio Code para expressar essas camadas.

Criando o template Clean Architecture na Asp .NET Core

Crie uma pasta onde deseja armazenar o projeto. No exemplo eu vou criar uma pasta Asp_CleanArch1.

A seguir entre na pasta (cd Asp_CleanArch1) e digite o comando para criar a solução:

dotnet new sln

Com isso temos o arquivo de solução Asp_CleanArch1.sln criado.

Vamos agora criar 4 projetos nesta pasta usando os seguintes comandos e nomes de projeto:

  1. dotnet new classlib -o Asp_CleanArch1.Core
  2. dotnet new classlib -o Asp_CleanArch1.Infrastructure
  3. dotnet new mvc -o Asp_CleanArch1.Presentation
  4. dotnet new xunit -o Asp_CleanArch1.Tests

Ao final teremos na pasta Asp_CleanArch1 os seguintes projetos criados:

Agora precisamos incluir cada projeto criado como uma referência na solução.

Para isso vamos emitir o seguinte comando para cada projeto:

dotnet sln Asp_CleanArch1.sln add .\Asp_CleanArch1.Core\Asp_CleanArch1.Core.csproj

dotnet sln Asp_CleanArch1.sln add .\Asp_CleanArch1.Infrastructure\Asp_CleanArch1.Infrastructure.csproj

dotnet sln Asp_CleanArch1.sln add .\Asp_CleanArch1.Presentation\Asp_CleanArch1.Presentation.csproj

dotnet sln Asp_CleanArch1.sln add .\Asp_CleanArch1.Tests\Asp_CleanArch1.Tests.csproj

Ao abrir o arquivo Asp_CleanArch1.sln podemos constatar a inclusão dos projetos na solução:

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.26124.0
MinimumVisualStudioVersion = 15.0.26124.0
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Asp_CleanArch1.Core", "Asp_CleanArch1.Core\Asp_CleanArch1.Core.csproj", "{7C90A9D9-74DF-4DA3-A9D3-5AFC74964E20}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Asp_CleanArch1.Infrastructure", "Asp_CleanArch1.Infrastructure\Asp_CleanArch1.Infrastructure.csproj", "{1EA5BF95-B337-4656-A146-4653135C85AD}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Asp_CleanArch1.Presentation", "Asp_CleanArch1.Presentation\Asp_CleanArch1.Presentation.csproj", "{45D56D35-486A-468F-8259-A7D72F9E0748}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Asp_CleanArch1.Tests", "Asp_CleanArch1.Tests\Asp_CleanArch1.Tests.csproj", "{451DA4B0-052B-4318-A8A6-690521D50ACE}"
EndProject
Global
...
 

Vamos agora abrir a solução no VS Code para isso , a partir da pasta Asp_CleanArch1, digite :  code .

Veremos a seguinte janela exibindo os projetos e o arquivo solution:



Essa seria a primeira etapa, a criação da estrutura do projeto seguindo a arquitetura limpa.

Na verdade você pode customizar essa estrutura alterando os nomes e incluindo em cada projeto mais pastas para organizar o código dependendo do escopo do seu projeto.

Em outro artigo veremos como criar uma aplicação completa usando esse template.

E estamos conversados...

"Visto como na sabedoria de Deus o mundo não conheceu a Deus pela sua sabedoria, aprouve a Deus salvar os crentes pela loucura da pregação.
Porque os judeus pedem sinal, e os gregos buscam sabedoria;
Mas nós pregamos a Cristo crucificado, que é escândalo para os judeus, e loucura para os gregos."
1 Coríntios 1:21-23

Referências:


José Carlos Macoratti