Communitygithub.com

Aurelian1974/TestRepo

Como construir e manter a Arquitetura Vertical Slice no .NET — anatomia das fatias (variantes de arquivo único e pasta), despacho direto de handlers sem um mediator, preocupações transversais, o que as fatias podem compartilhar, como as fatias interagem com um modelo de domínio ou camadas Clean, e testes em nível de fatia. Use ao adicionar ou modificar um caso de uso/endpoint/recurso em qualquer módulo organizado por fatias verticais, ou quando a duplicação entre fatias está sendo discutida.

O que é TestRepo?

Esta skill define padrões e práticas para implementar a **Vertical Slice Architecture** em projetos .NET. Ela detalha a anatomia de uma 'fatia' (slice) de feature, incluindo variantes de arquivo único e baseada em pastas, eliminando a necessidade de um mediator como o MediatR através do despacho direto de handlers. A skill também aborda como lidar com preocupações transversais (cross-cutting concerns), o que pode ser compartilhado entre fatias (ex.: entidades de domínio, interfaces de repositório) e como integrar a arquitetura com camadas Clean ou um modelo de domínio. Por fim, orienta sobre testes focados no nível da fatia para garantir isolamento e cobertura. É útil para desenvolvedores que estão adicionando novas funcionalidades, refatorando endpoints ou discutindo duplicação entre módulos em um sistema já organizado em fatias verticais.

Funciona com~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/Aurelian1974/TestRepo/tree/main/.claude/skills/vertical-slice-architecture

Perguntar na sua IA favorita

Abre um novo chat com esta habilidade de agente já pré-carregada.

Documentação

O que TestRepo faz?

Como construir e manter a Arquitetura Vertical Slice no .NET — anatomia das fatias (variantes de arquivo único e pasta), despacho direto de handlers sem um mediator, preocupações transversais, o que as fatias podem compartilhar, como as fatias interagem com um modelo de domínio ou camadas Clean, e testes em nível de fatia. Use ao adicionar ou modificar um caso de uso/endpoint/recurso em qualquer módulo organizado por fatias verticais, ou quando a duplicação entre fatias está sendo discutida.

Anatomia de uma Fatia

Uma fatia vertical representa uma única funcionalidade ponta a ponta. Ela pode ser implementada como:

  • Arquivo Único: Um único arquivo .cs contendo Request, Handler e Response.
  • Pasta: Uma pasta contendo arquivos separados para Request, Handler, Response e, opcionalmente, Validação e Mapeamento.

Exemplo de Fatia (Arquivo Único)

public class GetUserById
{
    public record Query(int UserId);
    public record Response(int Id, string Name, string Email);

    public class Handler
    {
        public async Task<Response> Handle(Query query, IUserRepository repo)
        {
            var user = await repo.GetByIdAsync(query.UserId);
            return new Response(user.Id, user.Name, user.Email);
        }
    }
}

Despacho Direto sem Mediator

Evite o uso de um mediator. Em vez disso, injete diretamente o Handler como um serviço:

// Registro no DI
services.AddScoped<GetUserById.Handler>();

// Uso no Controller ou Endpoint
public class UsersController : ControllerBase
{
    [HttpGet("{userId}")]
    public async Task<IActionResult> Get(int userId, [FromServices] GetUserById.Handler handler)
    {
        var result = await handler.Handle(new GetUserById.Query(userId));
        return Ok(result);
    }
}

Preocupações Transversais

Preocupações transversais como logging, validação e autorização podem ser aplicadas usando:

  • Decorators: Envolvendo o handler com um decorator para adicionar comportamento extra.
  • Filtros de Action: Aplicando globalmente ou por endpoint.
  • Atributos: Usando atributos customizados nos handlers.

O que as Fatias Podem Compartilhar

  • Modelo de Domínio: Entidades, Value Objects e Agregados são compartilhados.
  • Interfaces de Repositório: Abstrações para acesso a dados.
  • Contratos de Serviço: Interfaces para serviços externos.
  • Configuração: Classes de configuração e constantes.

Interação com Camadas Clean ou DDD

Cada fatia pode acessar diretamente ou ser composta por elementos de uma arquitetura em camadas:

  • Camada de Domínio: Contém as entidades, regras de negócio e interfaces.
  • Camada de Aplicação: Contém os handlers de caso de uso (que são as fatias).
  • Camada de Infraestrutura: Implementações de acesso a dados, serviços externos.

Exemplo de interação:

public class CreateOrderHandler
{
    private readonly IOrderRepository _repo;
    private readonly IEmailService _email;

    public CreateOrderHandler(IOrderRepository repo, IEmailService email)
    {
        _repo = repo;
        _email = email;
    }

    public async Task<Response> Handle(CreateOrderCommand command)
    {
        var order = Order.Create(command.CustomerId, command.Items); // Domínio
        await _repo.AddAsync(order); // Infraestrutura
        await _email.SendConfirmationAsync(order); // Infraestrutura
        return new Response(order.Id);
    }
}

Testes em Nível de Fatia

Teste cada fatia de forma isolada, mockando as dependências:

[Test]
public async Task GetUserById_ShouldReturnUser()
{
    var repo = new Mock<IUserRepository>();
    repo.Setup(r => r.GetByIdAsync(1)).ReturnsAsync(new User { Id = 1, Name = "John", Email = "[email protected]" });

    var handler = new GetUserById.Handler();
    var result = await handler.Handle(new GetUserById.Query(1), repo.Object);

    Assert.AreEqual("John", result.Name);
}

Considerações Sobre Duplicação

  • Duplicação acidental: Quando duas fatias contêm lógica semelhante, considere extrair para um serviço compartilhado ou classe base.
  • Duplicação intencional: Às vezes é aceitável se a lógica serve a contextos diferentes que podem evoluir independentemente.
  • Ferramentas de análise: Use ferramentas como Roslyn analyzers para detectar duplicação entre fatias.

Habilidades Relacionadas