본문으로 건너뛰기
cccskills
무료GitHub에 공개

dotnet-10-csharp-14

Use when building .NET 10 or C# 14 applications; when using minimal APIs, modular monolith patterns, or feature folders; when implementing HTTP resilience, Options pattern, Channels, or validation; when seeing outdated patterns like old extension method syntax

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

설치 방법 보기

포함된 파일(8)

  • SKILL.md12.1 KB
  • anti-patterns.md9.4 KB
  • csharp-14.md4.9 KB
  • infrastructure.md11.6 KB
  • libraries.md4.4 KB
  • minimal-apis.md9.6 KB
  • security.md8.5 KB
  • testing.md12.2 KB

SKILL.md(원문)

설치하기 전에 에이전트에게 전달되는 지시 내용을 확인할 수 있습니다.

.NET 10 & C# 14 Best Practices

.NET 10 (LTS, Nov 2025) with C# 14. Covers minimal APIs, not MVC.

Official docs: .NET 10 | C# 14 | ASP.NET Core 10

Detail Files

FileTopics
csharp-14.mdExtension blocks, field keyword, null-conditional assignment
minimal-apis.mdValidation, TypedResults, filters, modular monolith, vertical slices
security.mdJWT auth, CORS, rate limiting, OpenAPI security, middleware order
infrastructure.mdOptions, resilience, channels, health checks, caching, Serilog, EF Core, keyed services
testing.mdWebApplicationFactory, integration tests, auth testing
anti-patterns.mdHttpClient, DI captive, blocking async, N+1 queries
libraries.mdMediatR, FluentValidation, Mapster, ErrorOr, Polly, Aspire

Quick Start

<Project Sdk="Microsoft.NET.Sdk.Web">
  <PropertyGroup>
    <TargetFramework>net10.0</TargetFramework>
    <LangVersion>14</LangVersion>
    <Nullable>enable</Nullable>
  </PropertyGroup>
</Project>
```text

```csharp
var builder = WebApplication.CreateBuilder(args);

// Core services
builder.Services.AddValidation();
builder.Services.AddProblemDetails();
builder.Services.AddOpenApi();

// Security
builder.Services.AddAuthentication().AddJwtBearer();
builder.Services.AddAuthorization();
builder.Services.AddRateLimiter(opts => { /* see security.md */ });

// Infrastructure
builder.Services.AddHealthChecks();
builder.Services.AddOutputCache();

// Modules
builder.Services.AddUsersModule();

var app = builder.Build();

// Middleware (ORDER MATTERS - see security.md)
app.UseExceptionHandler();
app.UseHttpsRedirection();
app.UseCors();
app.UseRateLimiter();
app.UseAuthentication();
app.UseAuthorization();
app.UseOutputCache();

app.MapOpenApi();
app.MapHealthChecks("/health");
app.MapUsersEndpoints();
app.Run();
```text

---

## Decision Flowcharts

### Result vs Exception

```dot
digraph {
    "Error type?" [shape=diamond];
    "Expected?" [shape=diamond];
    "Result<T>/ErrorOr" [shape=box];
    "Exception" [shape=box];
    "Error type?" -> "Expected?" [label="domain"];
    "Error type?" -> "Exception" [label="infrastructure"];
    "Expected?" -> "Result<T>/ErrorOr" [label="yes"];
    "Expected?" -> "Exception" [label="no"];
}
```text

### IOptions Selection

```dot
digraph {
    "Runtime changes?" [shape=diamond];
    "Per-request?" [shape=diamond];
    "IOptions<T>" [shape=box];
    "IOptionsSnapshot<T>" [shape=box];
    "IOptionsMonitor<T>" [shape=box];
    "Runtime changes?" -> "IOptions<T>" [label="no"];
    "Runtime changes?" -> "Per-request?" [label="yes"];
    "Per-request?" -> "IOptionsSnapshot<T>" [label="yes"];
    "Per-request?" -> "IOptionsMonitor<T>" [label="no"];
}
```text

### Channel Type

```dot
digraph {
    "Trust producer?" [shape=diamond];
    "Can drop?" [shape=diamond];
    "Bounded+Wait" [shape=box,style=filled,fillcolor=lightgreen];
    "Bounded+Drop" [shape=box];
    "Unbounded" [shape=box];
    "Trust producer?" -> "Unbounded" [label="yes"];
    "Trust producer?" -> "Can drop?" [label="no"];
    "Can drop?" -> "Bounded+Drop" [label="yes"];
    "Can drop?" -> "Bounded+Wait" [label="no"];
}
```text

---

## Key Patterns Summary

### C# 14 Extension Blocks

```csharp
extension<T>(IEnumerable<T> source)
{
    public bool IsEmpty => !source.Any();
}
```text

### .NET 10 Built-in Validation

```csharp
builder.Services.AddValidation();
app.MapPost("/users", (UserDto dto) => TypedResults.Ok(dto));
```text

### TypedResults (Always Use)

```csharp
app.MapGet("/users/{id}", async (int id, IUserService svc) =>
    await svc.GetAsync(id) is { } user
        ? TypedResults.Ok(user)
        : TypedResults.NotFound());
```text

### Module Pattern

```csharp
public static class UsersModule
{
    public static IServiceCollection AddUsersModule(this IServiceCollection s) => s
        .AddScoped<IUserService, UserService>();

    public static IEndpointRouteBuilder MapUsersEndpoints(this IEndpointRouteBuilder app)
    {
        var g = app.MapGroup("/api/users").WithTags("Users");
        g.MapGet("/{id}", GetUser.Handle);
        return app;
    }
}
```text

### HTTP Resilience

```csharp
builder.Services.AddHttpClient<IApi, ApiClient>()
    .AddStandardResilienceHandler();
```text

### Error Handling (RFC 9457)

```csharp
builder.Services.AddProblemDetails();
app.UseExceptionHandler();
app.UseStatusCodePages();
```text

---

## MANDATORY Patterns (Always Use These)

| Task                | ✅ ALWAYS Use                    | ❌ NEVER Use                         |
| ------------------- | -------------------------------- | ------------------------------------ |
| Extension members   | C# 14 `extension<T>()` blocks    | Traditional `this` extension methods |
| Property validation | C# 14 `field` keyword            | Manual backing fields                |
| Null assignment     | `obj?.Prop = value`              | `if (obj != null) obj.Prop = value`  |
| API returns         | `TypedResults.Ok()`              | `Results.Ok()`                       |
| Options validation  | `.ValidateOnStart()`             | Missing validation                   |
| HTTP resilience     | `AddStandardResilienceHandler()` | Manual Polly configuration           |
| Timestamps          | `DateTime.UtcNow`                | `DateTime.Now`                       |

---

## Quick Reference Card

```text
┌─────────────────────────────────────────────────────────────────┐
│                    .NET 10 / C# 14 PATTERNS                      │
├─────────────────────────────────────────────────────────────────┤
│ EXTENSION PROPERTY:  extension<T>(IEnumerable<T> s) {           │
│                        public bool IsEmpty => !s.Any();         │
│                      }                                          │
├─────────────────────────────────────────────────────────────────┤
│ FIELD KEYWORD:       public string Name {                       │
│                        get => field;                            │
│                        set => field = value?.Trim();            │
│                      }                                          │
├─────────────────────────────────────────────────────────────────┤
│ OPTIONS VALIDATION:  .BindConfiguration(Section)                │
│                      .ValidateDataAnnotations()                 │
│                      .ValidateOnStart();   // CRITICAL!         │
├─────────────────────────────────────────────────────────────────┤
│ HTTP RESILIENCE:     .AddStandardResilienceHandler();           │
├─────────────────────────────────────────────────────────────────┤
│ TYPED RESULTS:       TypedResults.Ok(data)                      │
│                      TypedResults.NotFound()                    │
│                      TypedResults.Created(uri, data)            │
├─────────────────────────────────────────────────────────────────┤
│ ERROR PATTERN:       ErrorOr<User> or user?.Match(...)          │
├─────────────────────────────────────────────────────────────────┤
│ IOPTIONS:            IOptions<T>        → startup, no reload    │
│                      IOptionsSnapshot<T> → per-request reload   │
│                      IOptionsMonitor<T>  → live + OnChange()    │
└─────────────────────────────────────────────────────────────────┘
```text

---

## Anti-Patterns Quick Reference

| Anti-Pattern                 | Fix                                         |
| ---------------------------- | ------------------------------------------- |
| `new HttpClient()`           | Inject `HttpClient` or `IHttpClientFactory` |
| `Results.Ok()`               | `TypedResults.Ok()`                         |
| Manual Polly config          | `AddStandardResilienceHandler()`            |
| Singleton → Scoped           | Use `IServiceScopeFactory`                  |
| `GetAsync().Result`          | `await GetAsync()`                          |
| Exceptions for flow          | Use `ErrorOr<T>` Result pattern             |
| `DateTime.Now`               | `DateTime.UtcNow`                           |
| Missing `.ValidateOnStart()` | Always add to Options registration          |

See [anti-patterns.md](anti-patterns.md) for complete list.

---



## Code Navigation (Serena MCP)

**Primary approach:** Use Serena symbol operations for efficient code navigation:

1. **Find definitions**: `serena_find_symbol` instead of text search
2. **Understand structure**: `serena_get_symbols_overview` for file organization
3. **Track references**: `serena_find_referencing_symbols` for impact analysis
4. **Precise edits**: `serena_replace_symbol_body` for clean modifications

**When to use Serena vs traditional tools:**
- ✅ **Use Serena**: Navigation, refactoring, dependency analysis, precise edits
- ✅ **Use Read/Grep**: Reading full files, pattern matching, simple text operations
- ✅ **Fallback**: If Serena unavailable, traditional tools work fine

**Example workflow:**
```text
# Instead of:
Read: src/Services/OrderService.cs
Grep: "public void ProcessOrder"

# Use:
serena_find_symbol: "OrderService/ProcessOrder"
serena_get_symbols_overview: "src/Services/OrderService.cs"
```
## Libraries Quick Reference

| Library          | Package                                          | Purpose        |
| ---------------- | ------------------------------------------------ | -------------- |
| MediatR          | `MediatR`                                        | CQRS           |
| FluentValidation | `FluentValidation.DependencyInjectionExtensions` | Validation     |
| Mapster          | `Mapster.DependencyInjection`                    | Mapping        |
| ErrorOr          | `ErrorOr`                                        | Result pattern |
| Polly            | `Microsoft.Extensions.Http.Resilience`           | Resilience     |
| Serilog          | `Serilog.AspNetCore`                             | Logging        |

See [libraries.md](libraries.md) for usage examples.

리뷰

아직 리뷰가 없습니다. 사용해 본 소감을 남겨 주세요.

댓글

로그인 없이 쓸 수 있습니다. 사용 후기, 질문, 작동하지 않은 환경 등을 편하게 남겨 주세요.

아직 댓글이 없습니다. 첫 댓글을 남겨 보세요.

보내면 바로 공개됩니다. 이메일 주소나 전화번호 같은 개인 정보는 쓰지 마세요. URL은 2개까지입니다.

0 / 1,000자

이 양식은 reCAPTCHA로 보호되며 Google 개인정보처리방침 및 서비스 약관이 적용됩니다.

같은 저장소의 스킬

Patterns and techniques for evaluating and improving AI agent outputs.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

rudironsoni/Synaxis22026년 3월 17일 업데이트

Comprehensive AI prompt engineering safety review and improvement prompt. Analyzes prompts for safety, bias, security vulnerabilities, and effectiveness while providing detailed improvement recommendations.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

rudironsoni/Synaxis22026년 3월 17일 업데이트

Use when user requests research requiring multiple sources, comprehensive analysis, or synthesis across topics - technical research, domain knowledge gathering, market analysis, or learning about complex subjects

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

rudironsoni/Synaxis22026년 3월 17일 업데이트

deep-wiki

무료

AI-powered wiki generation for code repositories with commands, agents, and skills

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

rudironsoni/Synaxis22026년 3월 17일 업데이트

Implements accessible .NET UI. SemanticProperties, ARIA, AutomationPeer, testing per platform.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

rudironsoni/Synaxis22026년 3월 17일 업데이트

Adds analyzer packages to a project. Nullable, trimming, AOT compat analyzers, severity config.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

rudironsoni/Synaxis22026년 3월 17일 업데이트

rudironsoni의 스킬 모두 보기

이 스킬의 문제 신고