Communitygithub.com

GuerthCastro/claude-skills-dotnet

.NET 코딩 및 테스트 규칙을 Agent Skill로 패키징: C# 스타일, 테스트 패턴, SOLID 및 클린 아키텍처 리뷰, C# 14/.NET 10 기능 참조를 제공합니다. Claude Code, Claude 앱 및 SKILL.md를 읽는 모든 도구에서 작동합니다. MIT 라이선스.

claude-skills-dotnet란 무엇인가요?

이 Agent Skill은 .NET 및 C# 코드 리뷰를 위한 전문적인 SOLID 원칙 평가 도구입니다. Claude Code, Cursor, Codex와 같은 AI 코딩 어시스턴트와 함께 사용하도록 설계되었으며, SKILL.md 파일을 읽을 수 있는 모든 도구에서 작동합니다. 개발자가 제공한 코드를 분석하여 단일 책임 원칙(SRP), 개방-폐쇄 원칙(OCP), 리스코프 치환 원칙(LSP), 인터페이스 분리 원칙(ISP), 의존성 역전 원칙(DIP)의 다섯 가지 원칙을 독립적으로 평가합니다. 각 위반 사항을 심각도(치명적, 주요, 사소)별로 분류하고, 구체적인 리팩토링 버전을 제시합니다. 또한 클린 아키텍처 계층 위반 (예: 도메인 엔터티가 인프라 타입을 임포트하는 경우)도 식별합니다. C# 엔터티, 애플리케이션 핸들러, Angular 서비스, React 컴포넌트 등 다양한 언어와 계층을 지원하며, 구조화된 보고서 형식을 사용하여 리뷰 결과를 명확하게 전달합니다.

지원 대상✓Claude Code~Codex CLI~Cursor
npx skills add GuerthCastro/claude-skills-dotnet

즐겨 사용하는 AI에게 물어보기

이 에이전트 스킬이 미리 로드된 새 채팅을 엽니다.

문서

SOLID 리뷰

저자: Guerth Castro (github.com/GuerthCastro). MIT 라이선스에 따라 사용이 허가되었습니다.

리뷰 프로세스

코드가 리뷰를 위해 제공되면:

  1. 언어와 계층을 식별합니다 (C# 도메인 엔터티, 애플리케이션 핸들러, Angular 서비스, React 컴포넌트 등).
  2. 다섯 가지 원칙 각각을 독립적으로 평가합니다.
  3. 아래 형식을 사용하여 구조화된 보고서를 생성합니다.
  4. 위반 사항을 심각도별로 정렬합니다: 치명적(아키텍처 위반) > 주요(유지보수성 저하) > 사소(스타일 선호).
  5. 모든 치명적 또는 주요 위반 사항에 대해 구체적인 리팩토링 버전을 제공합니다.

보고서를 불필요하게 길게 만들지 마십시오. 원칙이 실제로 충족되면 PASS라고 표시하고 넘어갑니다.

다섯 가지 원칙

S: 단일 책임 원칙 (Single Responsibility Principle)

하나의 클래스, 하나의 변경 이유.

찾아야 할 위반 사항:

  • 클래스가 데이터 액세스와 비즈니스 로직을 모두 수행합니다.
  • 서비스가 이메일을 보내고, 데이터를 검증하고, 데이터베이스에 씁니다.
  • 컴포넌트가 데이터를 가져오고, 형식을 지정하고, UI 상태를 관리합니다.
  • 핸들러가 여러 개의 관련 없는 작업을 조정합니다.
  • 여러 도메인에 걸친 10개 이상의 메서드를 가진 갓 클래스.

위반. OrderService는 검증, 지속성, 알림을 수행합니다. 알림 호출이 속하지 않는 부분입니다.

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;
    }
}

수정: 알림 서비스를 추출하고 핸들러가 두 호출을 조정하도록 합니다.

O: 개방-폐쇄 원칙 (Open/Closed Principle)

확장에는 열려 있고, 수정에는 닫혀 있습니다.

찾아야 할 위반 사항:

  • 모든 기능이 추가될 때마다 커지는 if/else if 체인 또는 타입 문자열이나 열거형에 대한 switch 블록.
  • 새로운 보고서 유형을 추가하려면 기존 보고서 서비스를 편집해야 합니다.
  • 새로운 결제 방법을 추가하려면 체크아웃 핸들러를 편집해야 합니다.
  • 추상화가 필요한 곳에 구체적인 의존성.

위반. 새로운 내보내기 형식은 이 메서드를 편집해야 함을 의미합니다.

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

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

    throw new NotSupportedException(format);
}

수정: 컨테이너에서 키로 해결되는 IInvoiceExporter 추상화와 PdfInvoiceExporter 및 ExcelInvoiceExporter 구현.

L: 리스코프 치환 원칙 (Liskov Substitution Principle)

하위 타입은 기본 타입을 대체할 수 있어야 합니다.

찾아야 할 위반 사항:

  • 파생 클래스가 상속된 멤버에 대해 NotImplementedException을 던집니다.
  • 재정의가 예상된 동작을 변경합니다: 무음 no-op, 다른 반환 형태, 새로운 예외 유형.
  • 일부 구현에서 의미 있게 구현할 수 없는 멤버를 선언하는 인터페이스.
  • 동작에 도달하기 위해 구체적인 타입으로 캐스팅: if (repository is SqlOrderRepository sql).

I: 인터페이스 분리 원칙 (Interface Segregation Principle)

어떤 클래스도 사용하지 않는 멤버를 구현하도록 강요받아서는 안 됩니다.

찾아야 할 위반 사항:

  • 15개 이상의 멤버가 있는 거대한 인터페이스에서 구현체가 3개만 사용하는 경우.
  • IRepository<T>가 모든 엔터티에 GetAll, GetById, Create, Update, Delete, Paginate, Search, BulkInsert를 강제하는 경우.
  • 읽기와 쓰기가 혼합된 서비스 인터페이스에서 소비자가 한쪽만 필요한 경우.

위반. 읽기 전용 보고 소비자가 Create, Update, 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);
}

수정: IOrderReader와 IOrderWriter로 분할합니다. 둘 다 필요한 곳에서 합성합니다.

D: 의존성 역전 원칙 (Dependency Inversion Principle)

구체화가 아닌 추상화에 의존하십시오.

찾아야 할 위반 사항:

  • 비즈니스 로직 내부에서 new로 서비스나 리포지토리를 인스턴스화하는 경우.
  • 서비스 내부의 SqlConnection 또는 NpgsqlConnection에 대한 직접적인 의존성.
  • 애플리케이션 계층이 인프라 타입을 임포트하는 경우.
  • 변경 가능한 상태를 보유하는 정적 서비스 클래스.

위반. 핸들러가 자체 구체적인 리포지토리와 연결을 생성합니다.

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

수정: 기본 생성자를 통해 IOrderRepository를 주입하고 구성 루트의 컨테이너에 등록합니다.

보고서 형식

각 리뷰에 대해 이 구조를 생성하십시오:

## SOLID 리뷰: [ClassName 또는 파일명]
**언어/계층:** C# 애플리케이션 핸들러, Angular 서비스 등

### S: 단일 책임
상태: PASS / 위반 (치명적, 주요, 사소)
발견: [클래스가 단일 책임을 넘어 수행하는 작업]
수정: [구체적인 조치]

### O: 개방-폐쇄
상태: PASS / 위반
발견: ...
수정: ...

### L: 리스코프 치환
상태: PASS / 위반 / 해당 없음 (상속 없음)
발견: ...

### I: 인터페이스 분리
상태: PASS / 위반 / 해당 없음 (인터페이스 없음)
발견: ...

### D: 의존성 역전
상태: PASS / 위반
발견: ...
수정: ...

### 우선 순위 위반 사항
1. [치명적] DIP: 핸들러가 구체적인 리포지토리를 인스턴스화함
2. [주요] SRP: 서비스가 알림 이메일도 보냄

### 리팩토링 버전
[전체 수정된 코드 블록]

클린 아키텍처 계층 위반 사항

SOLID 외에도 이러한 교차 문제를 지적하십시오:

  • 도메인 엔터티가 애플리케이션이나 인프라 타입을 임포트하는 경우 (의존성 방향 위반).
  • 컨트롤러에 핸들러에 속하는 비즈니스 로직이 포함된 경우.
  • 리포지토리가 도메인 엔터티 대신 DTO를 반환하는 경우. 매핑은 애플리케이션에 속합니다.
  • 인프라가 애플리케이션이나 도메인에 선언된 인터페이스를 구현하는 대신 외부 API를 직접 호출하는 경우.
  • 핸들러가 HttpContext에 접근하여 인프라 관심사를 애플리케이션 계층으로 유출하는 경우.
  • 잘못된 어셈블리에서의 DI 등록으로 인해 계층이 컴파일을 위해 하위를 참조해야 하는 경우.

관련 스킬