ASP.NET Core - Implementando Onion Architecture com CQRS - IV
Hoje vamos concluir a implementação da Onion Architecture em uma aplicação ASP .NET Core aplicando o CQRS. |
Continuando a terceira parte do artigo vamos implementar a Web API no projeto ApiAlunos.
Implementando os recursos da camada CrossCutting
Antes de iniciarmos a implementação da API na camada ApiAlunos precisamos definir os recursos da camada CrossCutting criada no projeto Infrastructure.
Talvez o nome CrossCutting não tenha sido o mais apropriado, pois nesta camada vamos definir a classe estática DependencyInjection e o método de extensão AddInfrastructure onde vamos registrar os serviços , os repositórios, o AutoMapper e o MediatR de forma a podermos injetar estes recursos na camada Presentation.
Nota: A rigor o termo CrossCutting ou responsabilidades transversais refere-se métodos comuns fornecidos por uma camada ou serviço específico usado por todas as camadas de uma aplicação. Seria como uma camada/serviço que cruza toda a hierarquia.
No nosso projeto a camada CrossCutting faz parte da Infrastructure e será usada para registrar os serviços e recursos que serão usados na API.
Esta camada vai precisar ter uma referência aos projetos : Application e Persistence.
Assim vamos criar a classe DependencyInjection com o código abaixo:
using Application.Interfaces; using Application.Mappings; using Application.Services; using Domain.Interfaces; using MediatR; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Persistence.Context; using Persistence.Repositories; using System;
namespace CrossCutting
services.AddScoped<IAlunoRepository, AlunoRepository>(); services.AddAutoMapper(typeof(DomainToDtoMappingProfile));
var myhandlers = AppDomain.CurrentDomain.Load("Application"); return services; |
Pronto, agora poderemos carregar os serviços definidos nesta camada na classe Startup do projeto API.
Criando a Web API no projeto ApiAlunos
Para iniciar vamos definir a chamada do método de extensão AddInfrastructure no método ConfigureServices da classe Startup do projeto ApiAlunos:
public void ConfigureServices(IServiceCollection services) { services.AddInfrastructure(Configuration); services.AddControllers();
services.AddSwaggerGen(c => |
No arquivo appsettings.json temos que definir a string de conexão com o banco de dados SQL Server usado no projeto:
{ "ConnectionStrings": { "DefaultConnection": "SUA_INSTANCIA;Initial Catalog=OnionDBTeste;Integrated Security=True" }, "Logging": { "LogLevel": { "Default": "Information", "Microsoft": "Warning", "Microsoft.Hosting.Lifetime": "Information" } }, "AllowedHosts": "*" } |
Aqui você deve usar a sua string de conexão. (O nome do banco de dados usado : OnionDBTeste)
Criando o controlador AlunosController
Vamos criar o controlador AlunosController na pasta Controllers com o código abaixo:
using Application.DTOs; using Application.Interfaces; using Microsoft.AspNetCore.Mvc; using System.Collections.Generic; using System.Threading.Tasks;
namespace ApiAlunos.Controllers [HttpGet("{id}", Name = "GetAluno")] [HttpPost] await _alunoService.CreateAsync(alunoDto); return new CreatedAtRouteResult("GetAluno", [HttpPut("{id}")] if (alunoDto == null) await _alunoService.UpdateAsync(id, alunoDto); return Ok(alunoDto); [HttpDelete("{id}")] if (alunoDto == null) await _alunoService.DeleteAsync(id); return Ok(alunoDto); |
No controlador estamos injetando um instância do serviço IAlunoService e realizando as operações para incluir, alterar, consultar e excluir dados de um aluno usando os verbos HTTP Get, Post, Put e Delete.
Agora é só alegria ...
Executando o projeto teremos a apresentação dos endpoints da API exibidos na interface do Swagger:
E assim implementamos em um pequeno projeto a Arquitetura Cebola ou Onion Architecture onde temos um código desacoplado que é mais fácil de estender e manter.
A implementação do CQRS feita foi a mais simples e arcaica possível , e estamos usando apenas uma base de dados, realizando apenas as separações dos comandos e consultas. Existem implementações mais elaboradas que usam duas bases de dados, a base para leitura e a base para escrita que permite otimizar e obter um melhor desempenho na aplicação do padrão CQRS.
Pegue o projeto aqui : OnionArch.zip (sem as referências no projeto API)
"como está escrito:
Não há justo, nem um sequer, não há quem entenda, não há quem busque a Deus;
todos se extraviaram, à uma se fizeram inúteis; não há quem faça o bem, não
há nem um sequer."
Romanos 3:10-12
Referências:
C# - Entendo o I/O na plataforma .NET
C# - Fluxo assíncrono ou async streams