Skip to main content Skills Marketplace Descubra e explore skills de IA criadas pela comunidade.
Instalar com Codex ou Claude Copie este prompt, cole no Codex, Claude ou outro assistente e deixe que ele revise a página da skill e instale para você.
Copiar promptMostrar detalhes do prompt Um comando direto ignora o prompt de revisão. Verifique a origem antes de executá-lo.
npx skills add https://github.com/skeletorflet/opencode-kit --skill dotnet-expertO comando permanece em uma só linha. Role horizontalmente para revisá-lo antes de copiar.
Prefere uma cópia local? Baixe os arquivos disponíveis atualmente no SkillsMP.
Baixar Zip Baixando... Ocupações relacionadas SOC
Baseado na classificação ocupacional SOC
name dotnet-expert description .NET development principles and decision-making. .NET 8, ASP.NET Core, C# 12, dependency injection, best practices.
.NET Expert - Modern .NET 8
.NET development principles and decision-making.
Learn to THINK, not copy-paste patterns.
⚠️ How to Use This Skill
This skill teaches decision-making principles for .NET development.
ASK user for project type (web API, worker, blazor)
Choose minimal APIs vs controller-based
Don't use outdated .NET Framework patterns
1. Framework Selection
Decision Tree
What are you building?
│
├── REST API
│ ├── Minimal APIs (NEW .NET 6+) - Recommended for simple APIs
│ └── Controller-based - Complex operations, heavy validation
│
├── Full-stack Web
│ ├── Blazor Server - Server-rendered, WebSocket
│ ├── Blazor WebAssembly - Client-side, PWA-ish
│ └── ASP.NET Core MVC - Traditional Razor
│
├── Background Worker
│ └── .NET Worker Services + Quartz/Hangfire
│
├── gRPC Services
│ └── .NET gRPC (protobuf)
│
├── Desktop
│ ├── WPF (.NET 8)
│ ├── WinForms (legacy)
│ └── MAUI (cross-platform)
│
└── Microservices
└── .NET 8 + Dapr (cloud-native patterns)
Comparison: Minimal APIs vs Controllers
Factor Minimal APIs Controllers Boilerplate Very Low Medium Routing Inline/Fluent Attribute-based Validation Manual/FluentValidation DataAnnotations Best For Microservices, simple APIs
Enterprise, complex validation
OpenAPI/Swagger Built-in Route-based
2. Modern C# 12 Features
Primary Constructors
public class UserService (
IUserRepository userRepository,
IEmailService emailService )
{
public User? GetById(int id)
{
return userRepository.FindById(id);
}
}
public record User (int Id, string Name, string Email ) ;
Collection Expressions
var list = new List<int > { 1 , 2 , 3 };
int [] array = new int [] { 1 , 2 , 3 };
var list = [1 , 2 , 3 ];
int [] array = [1 , 2 , 3 ];
var dict = new Dictionary<string , int > { {"a" , 1 } };
var dict2 = ["a" , 1 ];
LINQ Improvements
var result = items
.Where(x => x.IsActive)
.OrderBy(x => x.Name)
.Select(x => x.ToDto())
.ToList();
var countByCategory = products.CountBy(p => p.Category);
Pattern Matching
public string Describe (object obj ) => obj switch
{
int i => $"Integer: {i} " ,
string s => $"String: {s.ToUpper()} " ,
User { Name: "Admin" } => "Admin user!" ,
User u => $"User: {u.Name} " ,
null => "Null!" ,
_ => $"Type: {obj.GetType().Name} "
};
3. Dependency Injection
.NET 8 DI (Built-in)
var builder = WebApplication.CreateBuilder(args );
builder.Services.AddScoped<IUserRepository, UserRepository>();
builder.Services.AddTransient<IEmailService, EmailService>();
builder.Services.AddSingleton<IConfigService, ConfigService>();
builder.Services.Configure<DatabaseOptions>(
builder.Configuration.GetSection("Database" ));
var app = builder.Build();
app.MapGet("/users/{id}" , (IUserRepository repo, int id)
=> repo.FindById(id));
Constructor Injection
public class UserService (IUserRepository repository )
{
private readonly IUserRepository _repo = repository;
public User? GetById(int id) => _repo.FindById(id);
}
public record EmailService (SmtpConfig Config ) : IEmailService
{
public async Task SendAsync (string to, string subject, string body )
{
}
}
4. Minimal APIs (Recommended)
Basic Pattern
var builder = WebApplication.CreateBuilder(args );
builder.Services.AddDbContext<AppDbContext>();
builder.Services.AddScoped<IUserRepository, UserRepository>();
var app = builder.Build();
app.MapGet("/api/users" , async (AppDbContext db)
=> await db.Users.ToListAsync());
app.MapGet("/api/users/{id}" , async (int id, AppDbContext db)
=> await db.Users.FindAsync(id));
app.MapPost("/api/users" , async (User user, AppDbContext db) =>
{
db.Users.Add(user);
await db.SaveChangesAsync();
return Results.Created($"/api/users/{user.Id} " , user);
});
app.Run();
With Validation
public record CreateUserRequest (string Name, string Email ) ;
app.MapPost("/api/users" , async (CreateUserRequest request,
IValidator<CreateUserRequest> validator,
AppDbContext db) =>
{
var validation = await validator.ValidateAsync(request);
if (!validation.IsValid)
return Results.BadRequest(validation.Errors);
var user = new User { Name = request.Name, Email = request.Email };
db.Users.Add(user);
await db.SaveChangesAsync();
return Results.Created($"/api/users/{user.Id} " , user);
});
5. Database Access
Entity Framework Core
public class AppDbContext : DbContext
{
public AppDbContext (DbContextOptions<AppDbContext> options )
: base (options ) {}
public DbSet<User> Users => Set<User>();
public DbSet<Order> Orders => Set<Order>();
}
public class User
{
public int Id { get ; set ; }
public string Name { get ; set ; } = "" ;
public string Email { get ; set ; } = "" ;
public DateTime CreatedAt { get ; set ; }
}
var users = await context.Users
.Where(u => u.IsActive)
.OrderBy(u => u.Name)
.Select(u => new UserDto(u.Id, u.Name))
.ToListAsync();
Dapper for Performance
public class UserRepository : IUserRepository
{
private readonly DbConnection _connection;
public async Task <User ?> FindById (int id )
{
return await _connection.QueryFirstOrDefaultAsync<User>(
"SELECT * FROM Users WHERE Id = @Id" ,
new { Id = id });
}
}
Comparison Approach Best For Performance EF Core Most CRUD, migrations Good Dapper Raw SQL, high performance Excellent ADO.NET Minimal overhead Best
6. Testing Patterns
xUnit with Moq
public class UserServiceTest
{
[Fact ]
public void GetById_WhenExists_ReturnsUser ()
{
var mockRepo = new Mock<IUserRepository>();
mockRepo.Setup(r => r.FindById(1 ))
.Returns(new User(1 , "test@test.com" ));
var service = new UserService(mockRepo.Object);
var result = service.GetById(1 );
Assert.NotNull(result);
Assert.Equal("test@test.com" , result.Email);
}
}
public class UserApiTest : IClassFixture <WebApplicationFactory <Program >>
{
private readonly HttpClient _client;
public UserApiTest (WebApplicationFactory<Program> factory )
{
_client = factory.CreateClient();
}
[Fact ]
public async Task GetUsers_ReturnsOk ()
{
var response = await _client.GetAsync("/api/users" );
Assert.True(response.IsSuccessStatusCode);
}
}
Testing Tools Tool Purpose xUnit Unit/Integration testing Moq Mocking framework FluentAssertions Fluent assertions Testcontainers.Sqlite In-memory DB testing WireMock HTTP mocking
7. Configuration
Options Pattern
public class DatabaseOptions
{
public string ConnectionString { get ; set ; } = "" ;
public int MaxConnections { get ; set ; } = 10 ;
}
{
"Database" : {
"ConnectionString" : "Server=.;Database=mydb;" ,
"MaxConnections" : 20
}
}
builder.Services.Configure<DatabaseOptions>(
builder.Configuration.GetSection("Database" ));
public class UserService (
IOptions<DatabaseOptions> options )
{
public string ConnString =>
options.Value.ConnectionString;
}
8. Error Handling
Global Exception Handler
app.UseExceptionHandler(errorApp =>
{
errorApp.Run(async context =>
{
context.Response.StatusCode = 500 ;
context.Response.ContentType = "application/json" ;
await context.Response.WriteAsync(
"{\"error\": \"An unexpected error occurred\"}" );
});
});
app.MapPost("/api/users" , async ([FromBody] User user) =>
{
try
{
}
catch (Exception ex)
{
return Results.Problem(detail: ex.Message,
statusCode: 400 );
}
});
9. Decision Checklist
❌ Anti-Patterns to Avoid
❌ DON'T:
Use synchronous I/O in API endpoints
Configure EF Core without tracking changes awareness
Use ViewBag/ViewData in minimal APIs
Skip health checks in microservices
Use .NET Framework patterns in .NET 8
Skip connection string encryption for production
✅ DO:
Use Primary Constructors (C# 12)
Use records for DTOs and responses
Use Minimal APIs for simple services
Use IAsyncEnumerable for streaming
Configure health checks (/healthz)
Use FluentValidation for complex validation
Remember: .NET 8 is modern and productive.
Use Minimal APIs, records, and primary constructors.
Think in modern .NET, not .NET Framework.