Communitygithub.com

GuerthCastro/claude-skills-dotnet

Convenções de codificação e teste .NET empacotadas como Skills de Agente: estilo C#, padrões de teste, revisão SOLID e Arquitetura Limpa, além de uma referência de recursos C# 14 / .NET 10. Funciona com Claude Code, aplicativos Claude e qualquer ferramenta que leia SKILL.md. MIT.

O que é claude-skills-dotnet?

Este skill é projetado para auxiliar agentes de IA (como Claude Code) a revisar código .NET com base em princípios SOLID e Arquitetura Limpa, identificar violações de design, e sugerir refatorações concretas. Ele fornece um processo estruturado para avaliar cada um dos cinco princípios SOLID (Responsabilidade Única, Aberto/Fechado, Substituição de Liskov, Segregação de Interfaces e Inversão de Dependência), além de detectar problemas de camadas como dependências ilegais entre domínio, aplicação e infraestrutura. O relatório gerado inclui classificação de severidade (Crítico, Maior, Menor) e versões refatoradas para violações Críticas e Maiores. Suporta qualquer ferramenta compatível com SKILL.md, tornando-o útil para revisões de código automatizadas em projetos C# modernos.

Funciona com✓Claude Code~Codex CLI~Cursor
npx skills add GuerthCastro/claude-skills-dotnet

Perguntar na sua IA favorita

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

Documentação

Revisão SOLID

Autor: Guerth Castro (github.com/GuerthCastro). Licenciado sob MIT.

Processo de Revisão

Quando o código é fornecido para revisão:

  1. Identifique a linguagem e a camada (entidade de domínio C#, handler de aplicação, serviço Angular, componente React, etc.).
  2. Avalie cada um dos cinco princípios de forma independente.
  3. Produza um relatório estruturado usando o formato abaixo.
  4. Classifique as violações por severidade: Crítico (quebra a arquitetura) sobre Maior (degrada a manutenibilidade) sobre Menor (preferência de estilo).
  5. Forneça uma versão refatorada concreta para toda violação Crítica ou Maior.

Não encha o relatório. Se um princípio for genuinamente satisfeito, diga PASS e prossiga.

Os cinco princípios

S: Princípio da Responsabilidade Única

Uma classe, uma razão para mudar.

Violações a serem procuradas:

  • Uma classe faz tanto acesso a dados quanto lógica de negócios.
  • Um serviço envia e-mails, valida dados e escreve no banco de dados.
  • Um componente busca dados, formata-os e gerencia o estado da UI.
  • Um handler orquestra várias operações não relacionadas.
  • Classes god com dez ou mais métodos abrangendo múltiplos domínios.

VIOLAÇÃO. OrderService valida, persiste e notifica. A chamada de notificação é a que não pertence.

public class OrderService(IOrderRepository repository, IEmailService email)
{
    public async Task<bool> AddItem(long orderId, long productId)
    {
        Order order = await repository.GetById(orderId);
        if (order.ItemCount >= order.MaxItems)
        {
            return false;
        }

        await repository.AddItem(orderId, productId);

        await email.SendOrderUpdated(orderId);
        return true;
    }
}

Correção: extrair um serviço de notificação e deixar o handler coordenar as duas chamadas.

O: Princípio Aberto/Fechado

Aberto para extensão, fechado para modificação.

Violações a serem procuradas:

  • Cadeias de if/else if ou blocos switch em strings de tipo ou enums que crescem a cada funcionalidade.
  • Adicionar um novo tipo de relatório requer editar o serviço de relatório existente.
  • Adicionar um novo método de pagamento requer editar o handler de checkout.
  • Dependências concretas onde uma abstração pertence.

VIOLAÇÃO. Um novo formato de exportação significa editar este método.

public byte[] ExportInvoice(string format, IEnumerable<InvoiceLine> lines)
{
    if (format == "pdf")
    {
        return GeneratePdf(lines);
    }

    if (format == "excel")
    {
        return GenerateExcel(lines);
    }

    throw new NotSupportedException(format);
}

Correção: uma abstração IInvoiceExporter com implementações PdfInvoiceExporter e ExcelInvoiceExporter, resolvidas por chave a partir do container.

L: Princípio da Substituição de Liskov

Subtipo devem ser substituíveis pelos seus tipos base.

Violações a serem procuradas:

  • Uma classe derivada lança NotImplementedException para um membro herdado.
  • Uma sobrescrita altera o comportamento esperado: um no-op silencioso, uma forma de retorno diferente, um novo tipo de exceção.
  • Uma interface declara membros que algumas implementações não podem implementar de forma significativa.
  • Casting para um tipo concreto para alcançar comportamento: if (repository is SqlOrderRepository sql).

I: Princípio da Segregação de Interfaces

Nenhuma classe deve ser forçada a implementar membros que não usa.

Violações a serem procuradas:

  • Interfaces gordas com quinze ou mais membros onde implementações usam três.
  • Um IRepository<T> genérico forçando GetAll, GetById, Create, Update, Delete, Paginate, Search e BulkInsert em toda entidade.
  • Uma interface de serviço misturando leituras e escritas quando consumidores precisam apenas de um lado.

VIOLAÇÃO. Um consumidor de relatório somente leitura é forçado a ver Create, Update e Delete.

public interface IOrderRepository
{
    Task<Order> GetById(long id);
    Task<IEnumerable<Order>> GetAll();
    Task Create(Order order);
    Task Update(Order order);
    Task Delete(long id);
}

Correção: dividir em IOrderReader e IOrderWriter. Compor onde ambos são necessários.

D: Princípio da Inversão de Dependência

Dependa de abstrações, não de concreções.

Violações a serem procuradas:

  • new instanciando um serviço ou repositório dentro da lógica de negócios.
  • Uma dependência direta de SqlConnection ou NpgsqlConnection dentro de um serviço.
  • A camada de Aplicação importando tipos de Infraestrutura.
  • Classes de serviço estáticas mantendo estado mutável.

VIOLAÇÃO. O handler constrói seu próprio repositório concreto e conexão.

public class GetOrderHandler
{
    public async Task<OrderDto> Handle(long id)
    {
        OrderRepository repository = new(new SqlConnection("..."));
        Order order = await repository.GetById(id);
        return order.MapToDto();
    }
}

Correção: injetar IOrderRepository através do construtor primário e registrá-lo no container na raiz de composição.

Formato do Relatório

Produza esta estrutura para cada revisão:

## Revisão SOLID: [NomeClasse ou nome do arquivo]
**Linguagem/Camada:** Handler de Aplicação C#, Serviço Angular, etc.

### S: Responsabilidade Única
Status: PASS / VIOLAÇÃO (Crítico, Maior, Menor)
Descoberta: [o que a classe faz além de sua responsabilidade única]
Correção: [ação concreta]

### O: Aberto/Fechado
Status: PASS / VIOLAÇÃO
Descoberta: ...
Correção: ...

### L: Substituição de Liskov
Status: PASS / VIOLAÇÃO / N/A (sem herança)
Descoberta: ...

### I: Segregação de Interfaces
Status: PASS / VIOLAÇÃO / N/A (sem interfaces)
Descoberta: ...

### D: Inversão de Dependência
Status: PASS / VIOLAÇÃO
Descoberta: ...
Correção: ...

### Violações prioritárias
1. [Crítico] DIP: handler instancia um repositório concreto
2. [Maior] SRP: serviço também envia o e-mail de notificação

### Versão refatorada
[bloco de código completo corrigido]

Violações de Camadas da Arquitetura Limpa

Além do SOLID, sinalize estes problemas transversais:

  • Uma entidade de Domínio importa tipos de Aplicação ou Infraestrutura (violação de direção de dependência).
  • Um controlador contém lógica de negócios que pertence a um handler.
  • Um repositório retorna DTOs em vez de entidades de domínio. Mapeamento pertence à Aplicação.
  • Infraestrutura chama uma API externa diretamente em vez de implementar uma interface declarada em Aplicação ou Domínio.
  • Um handler toca HttpContext, vazando uma preocupação de infraestrutura para a camada de aplicação.
  • Um registro de DI no assembly errado, fazendo com que uma camada tenha que referenciar para baixo para compilar.

Habilidades Relacionadas