dotnet

Use when working with C#, F#, .NET libraries, ASP.NET Core, Blazor, Entity Framework Core, and the broader .NET ecosystem. USE FOR: .NET language features, choosing libraries and frameworks, project structure, package selection, architecture decisions DO NOT USE FOR: specific library configuration details (use the sub-skills: web, data, testing, eventing, cloud, etc.)

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "dotnet" with this command: npx skills add tyler-r-kendrick/agent-skills/tyler-r-kendrick-agent-skills-dotnet

.NET

Overview

.NET is Microsoft's open-source, cross-platform framework for building web APIs, cloud services, desktop applications, mobile apps, games, IoT, and AI/ML solutions. The modern .NET platform (6+) unifies what were formerly separate runtimes (.NET Framework, .NET Core, Mono) into a single SDK. C# is the primary language, with F# for functional programming. The ecosystem spans 400,000+ NuGet packages, first-party Azure integration, and tooling through Visual Studio, VS Code, and JetBrains Rider.

Knowledge Map

dotnet/
├── ai/                    # ML.NET, ONNX, Azure AI, Microsoft.Extensions.AI, agents (A2A, MCP)
├── cli/                   # Spectre.Console, CliWrap, command-line cheatsheet
├── cloud/                 # Aspire, Azure Functions, Dapr, Orleans, service discovery
├── configuration/         # Extensions.Configuration, caching, feature flags, OpenFeature
├── data/                  # EF Core, Dapper, Redis, Lucene.NET, FluentStorage
├── dependency-injection/  # Extensions.DI, Generic Host, Spring.NET
├── documentation/         # OpenAPI / Swagger
├── eventing/              # MediatR, MassTransit, NServiceBus, Rebus, Wolverine, Brighter, Akka.NET
├── functional/            # F#, Language.Ext, FParsec, Optional, pidgin
├── general/               # Humanizer, ImageSharp, NodaTime, Stateless, worker services, cheatsheet
├── localization/          # i18n, resource-based localization, MessageFormat
├── logging/               # Serilog, NLog, Extensions.Logging
├── mapping/               # AutoMapper, Mapperly
├── networking/            # gRPC, DotNetty, MimeKit, System.IO.Pipelines, Twilio
├── observability/         # OTLP logging, OpenTelemetry conventions
├── project-system/        # MSBuild/csproj, Roslyn analyzers, source generators, EditorConfig, Fody
├── reactive/              # Rx.NET, System.Threading.Channels, DynamicData, IAsyncEnumerable
├── resilience/            # Polly, Extensions.Resilience
├── security/              # ASP.NET Identity, cryptography, authorization (Topaz, Enforcer)
├── serialization/         # Protobuf-net, Bond, Hyperion, FluentSerializer
├── testing/               # Testcontainers, Moq, AutoFixture, Pact, Reqnroll, Playwright
├── ui/                    # MAUI, Avalonia, Blazor, Uno Platform, Blazorise, MonoGame, Unity
├── validation/            # FluentValidation, Validot, Parse Don't Validate, CommunityToolkit.Guard
└── web/                   # ASP.NET Core, SignalR, YARP, Ocelot, GraphQL, Refit, Orchard CMS

Choosing Guide

ProblemSub-SkillNotes
Build a web API or microserviceweb/aspnet-coreMinimal APIs for simple endpoints, controllers for complex APIs
Add real-time push to a web appweb/signalrWebSocket abstraction with automatic fallback to SSE/long-polling
Reverse proxy or API gatewayweb/yarp or web/ocelotYARP for high-perf programmatic proxy, Ocelot for config-driven gateway
GraphQL APIweb/graphqlHot Chocolate server with filtering, sorting, subscriptions
Access a relational databasedata/entity-framework-coreFull ORM with migrations, change tracking, LINQ queries
Lightweight SQL queriesdata/dapperMicro-ORM, raw SQL with object mapping, best for read-heavy paths
Distributed cachedata/redis or configuration/extensions-cachingRedis for shared cache, IMemoryCache/IDistributedCache for local/hybrid
Event-driven / CQRS architectureeventing/mediatrIn-process mediator; combine with eventing/masstransit for cross-service
Message bus (RabbitMQ, Kafka, Azure SB)eventing/masstransitAbstraction over transports with sagas, retries, and outbox pattern
Build a .NET Aspire appcloud/aspireOrchestrate multi-project apps with built-in service discovery and telemetry
Serverless functionscloud/azure-functionsIsolated worker model for Azure Functions with DI and middleware
Resilience (retries, circuit breakers)resilience/pollyConfigurable policies; use resilience/extensions-resilience for DI integration
Structured logginglogging/serilogSinks for Console, Seq, Elasticsearch, Application Insights
Object mappingmapping/mapperlySource-generator-based mapper (zero reflection, compile-time safe)
Input validationvalidation/fluent-validationsFluent rules with DI integration and ASP.NET Core auto-validation
Integration testing with real DBstesting/testcontainersDocker-based throwaway containers for Postgres, SQL Server, Redis
Mocking in unit teststesting/moqProxy-based mocking with LINQ setup expressions
Contract testingtesting/pactConsumer-driven contract tests for microservice boundaries
BDD / Gherkintesting/reqnrollSpecFlow successor — Given/When/Then with .NET 8+ support
Cross-platform desktop appui/avaloniaXAML-based UI for Windows, macOS, Linux, iOS, Android, WebAssembly
Mobile + desktop from one codebaseui/mauiMicrosoft's official cross-platform UI framework (.NET 8+)
Interactive web UI in C#ui/blazorServer-side or WebAssembly rendering with Razor components
Functional programming in C#functional/language-extImmutable collections, Option/Either monads, pattern matching extensions
F# language guidancefunctional/fsharpType providers, computation expressions, pipelines, domain modeling
AI/ML inferenceai/microsoft-extensions-aiUnified abstraction for OpenAI, Azure AI, Ollama, and custom providers
Train ML models in .NETai/mlnetAutoML, classification, regression, anomaly detection, recommendation
Build a CLI toolcli/spectre-consoleRich terminal UI with tables, trees, progress bars, prompts
Source generatorsproject-system/generators-cheatsheetCompile-time code generation with Roslyn incremental generators
Roslyn code analysisproject-system/roslyn-analyzersCustom analyzers and code fixes for enforcing team conventions

.NET Version Landscape

VersionReleaseSupportKey Features
.NET 6Nov 2021LTS (ended Nov 2024)Minimal APIs, hot reload, DateOnly/TimeOnly, HTTP/3, AOT groundwork
.NET 7Nov 2022STS (ended May 2024)Native AOT for console apps, rate limiting middleware, output caching
.NET 8Nov 2023LTS (until Nov 2026).NET Aspire, FrozenDictionary, keyed DI, native AOT for web, TimeProvider
.NET 9Nov 2024STS (until May 2026)System.Threading.Lock, LINQ CountBy/AggregateBy, TypedResults improvements

Choosing a Version

  • Starting a new project? Use .NET 8 (LTS) for stability, or .NET 9 for latest features.
  • In production with .NET 6? Plan migration to .NET 8 — .NET 6 support has ended.
  • Need native AOT? .NET 8+ supports AOT for ASP.NET Core minimal APIs and gRPC.
  • Using Aspire for orchestration? Requires .NET 8+.

C# Quick Reference

Modern C# Features (10-13)

// Global usings (C# 10) — reduce boilerplate across files
global using System.Text.Json;
global using Microsoft.Extensions.Logging;

// File-scoped namespaces (C# 10)
namespace MyApp.Services;

// Records with positional syntax — immutable data types
public record OrderPlaced(Guid OrderId, string CustomerId, decimal Total, DateTime PlacedAt);

// Primary constructors (C# 12) — DI without field ceremony
public class OrderService(IOrderRepository repo, ILogger<OrderService> logger)
{
    public async Task<Order> GetAsync(Guid id)
    {
        logger.LogInformation("Fetching order {OrderId}", id);
        return await repo.FindAsync(id) ?? throw new NotFoundException(id);
    }
}

// Collection expressions (C# 12)
int[] numbers = [1, 2, 3, 4, 5];
List<string> names = ["Alice", "Bob", "Charlie"];
ReadOnlySpan<byte> header = [0x48, 0x54, 0x54, 0x50];

// Pattern matching with list patterns (C# 11)
string Describe(int[] values) => values switch
{
    [] => "empty",
    [var single] => $"one item: {single}",
    [var first, .., var last] => $"from {first} to {last}",
};

// Raw string literals (C# 11) — no escaping needed
var json = """
    {
        "name": "Widget",
        "price": 29.99,
        "tags": ["electronics", "sale"]
    }
    """;

// Required members (C# 11)
public class Config
{
    public required string ConnectionString { get; init; }
    public required int MaxRetries { get; init; }
    public TimeSpan Timeout { get; init; } = TimeSpan.FromSeconds(30);
}

// Switch expressions with property patterns
decimal CalculateDiscount(Order order) => order switch
{
    { Total: > 1000, Customer.IsPremium: true } => order.Total * 0.15m,
    { Total: > 500 } => order.Total * 0.10m,
    { Customer.IsPremium: true } => order.Total * 0.05m,
    _ => 0m,
};

Key NuGet Package Categories

CategoryGo-To PackagesWhen to Use
Web FrameworkASP.NET Core (built-in)REST APIs, Razor Pages, Blazor, gRPC
ORMEF Core, DapperEF Core for full ORM, Dapper for raw SQL performance
ValidationFluentValidation, ValidotFluent rule definitions, DI-friendly, auto-wire with ASP.NET
MappingMapperly, AutoMapperMapperly for source-gen (zero reflection), AutoMapper for convention-based
SerializationSystem.Text.Json, Protobuf-netSTJ for JSON (built-in), Protobuf for binary/gRPC
LoggingSerilog, NLogStructured logging with sinks for Seq, Elastic, AppInsights
TestingxUnit, Moq, AutoFixture, TestcontainersxUnit as test framework, Moq for mocks, Testcontainers for integration
ResiliencePolly, Extensions.ResilienceRetry, circuit breaker, timeout, rate limiter policies
MessagingMassTransit, MediatR, NServiceBusMassTransit for bus abstraction, MediatR for in-process CQRS
DIExtensions.DI (built-in)Constructor injection, scoped/transient/singleton lifetimes
CachingExtensions.Caching, StackExchange.RedisIMemoryCache for local, IDistributedCache for Redis/SQL
HTTP ClientRefit, RestSharpRefit for interface-defined clients, RestSharp for simpler REST calls
CLISpectre.Console, System.CommandLineRich terminal UIs, argument parsing, help generation
Cloud.NET Aspire, Azure.IdentityAspire for orchestration, Azure.Identity for managed identity auth

Best Practices

  1. Use the latest LTS release (.NET 8) for production workloads. LTS releases receive 3 years of security patches and bug fixes.

  2. Enable nullable reference types (<Nullable>enable</Nullable>) in every project. This catches null-reference bugs at compile time:

    <PropertyGroup>
      <TargetFramework>net8.0</TargetFramework>
      <Nullable>enable</Nullable>
      <ImplicitUsings>enable</ImplicitUsings>
    </PropertyGroup>
    
  3. Use IOptions<T> pattern for configuration instead of reading values directly. This provides validation, reload support, and testability:

    public class SmtpOptions
    {
        public const string Section = "Smtp";
        public required string Host { get; init; }
        public int Port { get; init; } = 587;
        public required string FromAddress { get; init; }
    }
    
    // In Program.cs
    builder.Services.AddOptions<SmtpOptions>()
        .BindConfiguration(SmtpOptions.Section)
        .ValidateDataAnnotations()
        .ValidateOnStart();
    
  4. Prefer records for data transfer objects and events. Records provide value equality, immutability, and concise syntax. Use record class for heap-allocated (default) and record struct for stack-allocated small types.

  5. Use primary constructors for DI in services and controllers (C# 12). This eliminates boilerplate private readonly fields while keeping constructor injection.

  6. Avoid async void — it swallows exceptions. Always return Task or ValueTask from async methods. The only exception is event handlers.

  7. Use CancellationToken everywhere — pass it through all async call chains so requests can be cancelled cleanly when clients disconnect:

    app.MapGet("/orders/{id}", async (Guid id, IOrderRepository repo, CancellationToken ct) =>
        await repo.FindAsync(id, ct) is { } order
            ? Results.Ok(order)
            : Results.NotFound());
    
  8. Register services with the correct lifetimeSingleton for stateless/thread-safe services, Scoped for per-request state (EF DbContext), Transient for lightweight stateless operations. Never inject Scoped into Singleton.

  9. Use source generators over reflection where available (Mapperly, System.Text.Json source gen, Roslyn analyzers). Source generators run at compile time, eliminate reflection costs, and are compatible with Native AOT.

  10. Structure solutions with clear project boundaries — separate API host, domain logic, infrastructure, and tests into distinct projects. Use <ProjectReference> and enforce dependency direction (domain has no external references).

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Automation

specs

No summary provided by upstream source.

Repository SourceNeeds Review
Automation

ai

No summary provided by upstream source.

Repository SourceNeeds Review
Automation

markdown-token-optimizer

No summary provided by upstream source.

Repository SourceNeeds Review
Automation

tools

No summary provided by upstream source.

Repository SourceNeeds Review