ASP.NET - Usando o padrão Specification - II


  Hoje vou continuar apresentando o padrão Specification mostrando uma implementação básica em uma aplicação ASP .NET  Core usando a Clean Architecture e o EF Core.

Continuando o artigo anterior vamos agora definir o código do projeto Web API - APiDev.

No arquivo appsettings.json vamos definir a string de conexão para acessar o banco de dados que iremos criar usando o Migrations do EF Core:

{
  "ConnectionStrings": {
    "DefaultConnection": "Data Source=.;Initial Catalog=DevsDB;Integrated Security=True;TrustServerCertificate=True;"
  },
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*"
}

Neste arquivo você deve definir a string de conexão do seu SQL Server Local. E no ambiente do .NET 7.0 deve usar a propriedade TrustServerCertificate=True no ambiente de desenvolvimento.

A seguir no arquivo Program vamos registrar o serviço do contexto e do repositório genèrico:

using Core.Interfaces;
using Data.Context;
using Data.Repositories;
using Microsoft.EntityFrameworkCore;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
var connectionSql = builder.Configuration.GetConnectionString("DefaultConnection");
builder.Services.AddDbContext<AppDbContext>(options =>
  options.UseSqlServer(connectionSql));
builder.Services.AddScoped(typeof(IGenericRepository<>), (typeof(GenericRepository<>)));
var app = builder.Build();
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run(); 

Agora na pasta Controllers vamos criar o controlador DesenvolvedoresController :

using Core.Entities;
using Core.Interfaces;
using Core.Specifications;
using Microsoft.AspNetCore.Mvc;
namespace ApiDev.Controllers;
[Route("api/[controller]")]
[ApiController]
public class DesenvolvedoresController : ControllerBase
{
    public readonly IGenericRepository<Desenvolvedor> _repository;
    public DesenvolvedoresController(IGenericRepository<Desenvolvedor> repository)
    {
        _repository = repository;
    }
    [HttpGet]
    public async Task<IActionResult> GetAll()
    {
        var desenvolvedores = await _repository.GetAllAsync();
        return Ok(desenvolvedores);
    }
    [HttpGet("{id}")]
    public async Task<IActionResult> GetById(int id)
    {
        var desenvolvedor = await _repository.GetByIdAsync(id);
        return Ok(desenvolvedor);
    }
    [HttpGet("endereco/{anos}")]
    public ActionResult EnderecosPorAnos(int anos)
    {
        var specification1 = new DesenvolvedorExperienciaEnderecoSpec(anos);
        var desenvolvedores = _repository.FindWithSpecificationPattern(specification1);
        return Ok(desenvolvedores);
    }
    [HttpGet("renda/{renda}")]
    public ActionResult RendaOrdenada(decimal renda)
    {
        var specification2 = new DesenvolvedorRendaEstimadaSpec(renda);
        var desenvolvedores = _repository.FindWithSpecificationPattern(specification2);
        return Ok(desenvolvedores);
    }
}

Como destaque temos os endpoints onde estamos usando o método FindWithSpecificationPattern da nossa implementação do padrão ISpecification.

Executando o projeto teremos o resultado abaixo:

Poderemos a seguir acionar os endpoints onde estamos usando as especificações definidas com a implementação do padrão :

1- /api/Desenvolvedores/endereco/8

2- /api/Desenvolvedores/renda/4500

E estamos conversados...

Pegue o projeto aqui:  https://github.com/macoratti/ApiDevSpecification ...

Referências:


José Carlos Macoratti