ASP .NET Core - Implementando a Onion Architecture - I


Neste artigo vamos criar uma aplicação ASP .NET Core WEBAPI  fazendo uma implementação básica da arquitetura em Cebola ou Onion Architecture.

Sei que você pode estar cansado de ver diagramas representando a Onion Architecture mas como existem diversas possibilidades para representar as camadas e existem muitos diagramas eu vou mostrar o diagrama no qual eu vou basear o este artigo.

Isso não significa que esta abordagem é mais correta que as demais. Significa apenas que é a minha abordagem.

Na Onion Architecture deve ser a Camada de Domínio (entidades e regras de validação comuns ao caso de negócios) que está no núcleo de todo o aplicativo. Isso significa maior flexibilidade e menor acoplamento. Nesta abordagem, podemos ver que todas as camadas dependem apenas das camadas principais e o fluxo sempre deve ser no sentido das camadas externas para as camadas internas.

Nesta figura Domain e Application são camadas que estarão no centro do design. Podemos nos referir a essas camadas como Camadas Principais ou Core Layers. Essas camadas não dependerão de nenhuma outra camada.

Nota:  Outra maneira de ver a Arquitetura Cebola é como uma cebola que você pode descascar. Se você descascar a camada externa com a infraestrutura, apresentação e testes, então, a camada interna (núcleo do aplicativo) ainda deve funcionar. Assim, o núcleo do aplicativo deve ser capaz de funcionar sem infraestrutura e apresentação.

A Camada de Domínio geralmente contém lógica corporativa e entidades. A camada de aplicativo teria interfaces e tipos. A principal diferença é que a camada de domínio terá os tipos que são comuns a toda a aplicação, portanto, também pode ser compartilhada por outras soluções. Mas a camada de aplicativo tem interfaces e tipos específicos de aplicativo.

Como as camadas principais nunca dependerão de nenhuma outra camada, como fazermos para acessar as camadas externas ?

A figura a seguir mostra o fluxo padrão de acesso às camadas. Sempre de fora para dentro.

Para isso o que fazemos é criar interfaces na Camada Application ou camada de Aplicativo e essas interfaces são implementadas nas camadas externas. Isso também é conhecido como DIP ou Princípio de Inversão de Dependência.

Por exemplo, se seu aplicativo precisar enviar um e-mail, definimos uma interface IMailService na camada de aplicativo e a implementamos fora das camadas principais. Usando o recurso da DIP, é possível alternar as implementações. Isso ajuda a construir aplicativos escaláveis.

A camada de infraestrutura é onde você deseja adicionar sua infraestrutura, banco de dados, etc.

A infraestrutura pode ser qualquer coisa. Talvez uma camada central do Entity Framework para acessar o banco de dados, ou uma camada feita especificamente para gerar tokens JWT para autenticação ou mesmo uma camada Hangfire. Geralmente nesta camada definimos a lógica de acesso aos dados e as configurações do EF Core e suas migrações quando isso for pertinente.

Note que definimos uma camada para Testes a serem realizados na aplicação.

Nesta implementação eu não vou definir a camada de testes e nem vou usar o padrão CQRS. Vou fazer uma implementação básica inicial para mostrar o básico a ser feito para implementar a Onion Architecture.

Recursos usados:

Criando a estrutura do projeto ASP .NET Core

Para organizar a estrutura do projeto vou fazer o seguinte:

Os nomes dos projetos da solução usarão o prefixo eStore seguindo de ponto e o nome do projeto. Teremos assim uma solução contendo 6 projetos:

Criando a Blank Solution

Abra o VS 2019 Community e clique em New Project selecionando o template Blank Solution:

Informe o nome eStore e clique em Create.

Criando as pastas na Solução eStore

Clique com o botão direito do mouse sobre a solução criada e selecione :

- Add -> New Solution Folder

A seguir digite o nome da pasta Core, repetindo o procedimento para as pastas Infrastructure e API.

Ao final você terá a Solution e 3 pastas conforme mostra a figura:

Estas pastas foram criadas para ajudar na organização do projeto.

Criando os projetos da pasta Core

Nesta pasta vamos criar os projetos eStore.Domain e eStore.Application.

Clique com o botão direito do mouse sobre a pasta Core e selecione Add-> New Project;

Selecione o template Class Library e clique em Next;

Informe o nome eStore.Domain e clique em Next;

A seguir selecione o Target Framework como .NET 5.0 (Current) conforme figura abaixo:

Clique em Create.

Repita este procedimento e crie o projeto eStore.Application nesta pasta.

Criando os projetos da pasta Infrastructure

Nesta pasta vamos criar os projetos :

O procedimento é o mesmo adotado para criar os projetos Class Library da pasta Core.

Criando o projeto ASP.NET Core Web API na pasta API

Clique com o botão direito do mouse sobre a pasta API e selecione  Add-> New Project;

Selecione o template ASP .NET Core Web API e clique em Next;

Informe o nome eStore.API e clique em Next;

A seguir selecione o Target Framework, Authentication Type e demais configurações conforme mostrada na figura:

Clique em Create.

A figura a seguir mostra a Solution Explorer com a estrutura do projeto criada:

No sistema de arquivos a visão da solução e dos projetos será a seguinte:

Definindo o projeto eStore.API como Startup Project e executando a solução iremos obter o resultado abaixo exibindo o endpoint definido na API usando já os recursos do Swagger:

Com isso concluímos a criação da estrutura do projeto e na próxima parte do artigo iremos iniciar a implementação da camada Core onde estão os projetos Domain e Application.

"Porque, se alguém cuida ser alguma coisa, não sendo nada, engana-se a si mesmo. Mas prove cada um a sua própria obra, e terá glória só em si mesmo, e não noutro."
Gálatas 6:3,4

Referências:


José Carlos Macoratti