.NET/C# Best Practices
SkillDev toolsEnsure .NET/C# code meets best practices for the solution/project.
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the .NET/C# Best Practices skill
What this skill tells your AI
The instructions your AI receives, as published by vixenlights/vixen in .agents/skills/dotnet-best-practices/SKILL.md and read by ahel’s review.
C# coding guidelines and best practices. MUST follow these rules. Use when reviewing/writing C# code or dotnet tasks.
Documentation & Structures
- Create comprehensive XML documentation comments for all public classes, interfaces, methods, and properties using the csharp-docs skill.
- Include parameter descriptions and return value descriptions in XML comments
- Follow the established namespace structure: {Core|Console|App|Service}.{Feature}
Design Patterns & Architecture
- Use primary constructor syntax for dependency injection (e.g.,
public class MyClass(IDependency dependency)) - Implement the Command Handler pattern with generic base classes (e.g.,
CommandHandler<TOptions>) - Use interface segregation with clear naming conventions (prefix interfaces with 'I')
- Follow the Factory pattern for complex object creation.
Syntax & Language Features
- Prefer Records for DTOs and messages to ensure immutability by default.
- NEVER mix multiple classes or DTOs in a single file, even if they are small. Filename ALWAYS matches the class or DTO name, for example UserDto.cs for a UserDto class.
- Use record structs and init accessors so that you can clone objects using the with keyword rather than tracking state mutations.
- Leverage Pattern Matching with switch expressions for cleaner logic flow.
- Utilize Collection Expressions and Span for high-performance data handling.
- Use expression bodies (arrow syntax) for methods, properties, and constructors when the logic is a simple transformation.
- For conditional assignments, replace bulky, nested if-else blocks or legacy switch statements with switch expressions.
- Use [ and ] for initializing arrays, lists, and spans. This offers a uniform, clean syntax across all collection types and eliminates redundant type declarations.
- One Class Per File: Ensure a strict structure with matching filenames.
- Use var for local variables when type is obvious.
- ALWAYS use sealed accessor for classes or records if not intended for inheritance.
- ALWAYS use internal accessor for internal classes or records.
- Don't use Regions in very small code files.
- Use Regions in large code files to group public properties.
- Use Regions in large code files to group event logic together.
Dependency Injection & Services
- Use constructor dependency injection with null checks via ArgumentNullException
- Register services with appropriate lifetimes (Singleton, Scoped, Transient)
- Use Microsoft.Extensions.DependencyInjection patterns
- Implement service interfaces for testability
Resource Management & Localization
- Use ResourceManager for localized messages and error strings
- Separate LogMessages and ErrorMessages resource files
- Access resources via
_resourceManager.GetString("MessageKey")
Async/Await Patterns
- Use async/await for all I/O operations and long-running tasks
- Return Task or Task from async methods
- Use ConfigureAwait(false) where appropriate
- Handle async exceptions properly
Testing Standards
- Use XUnit framework for unit tests.
- Follow AAA pattern (Arrange, Act, Assert)
- Use Moq for mocking dependencies
- Test both success and failure scenarios
- Include null parameter validation tests
Configuration & Settings
- Use strongly-typed configuration classes with data annotations
- Implement validation attributes (Required, NotEmptyOrWhitespace)
- Use IConfiguration binding for settings
- Support appsettings.json configuration files
Semantic Kernel & AI Integration
- Use Microsoft.SemanticKernel for AI operations
- Implement proper kernel configuration and service registration
- Handle AI model settings (ChatCompletion, Embedding, etc.)
- Use structured output patterns for reliable AI responses
Error Handling & Logging
- Use structured logging with Microsoft.Extensions.Logging or NLog
- Prefer NLog if it is already used
- ALWAYS Structured logging to log, no string interpolation and no other logging methods.
- Include scoped logging with meaningful context
- Throw specific exceptions with descriptive messages
- Use try-catch blocks for expected failure scenarios
- Use early exists with ArgumentNullException.ThrowIfNull(argument) instead of custom if (argument == null) checks.
Performance & Security
- Use C# 12+ features and .NET 8+ optimizations where applicable
- Implement proper input validation and sanitization
- Use parameterized queries for database operations
- Follow secure coding practices for AI/ML operations
Code Quality
- Ensure SOLID principles compliance
- Avoid code duplication through base classes and utilities
- Use meaningful names that reflect domain concepts
- Keep methods focused and cohesive
- Implement proper disposal patterns for resources
WPF
- UI Agnosticism: Never use WPF types (e.g., MessageBox, Panel, TextBox) inside the ViewModel. All UI interactions must go through interfaces or services (e.g., IDialogService).
- No Code-Behind: Only use XAML and Microsoft.Xaml.Behaviors.Wpf (EventToCommand) to trigger ViewModel logic. Code-behind must be strictly reserved for View-specific visual setups.
- One-to-One Binding: Enforce one View-Model per View and rely purely on data binding (e.g., {Binding PropertyName}) rather than accessing UI elements by their x:Name
Winforms
- Do not create any new UI using Winforms.
- Legacy Winforms UI can be maintained.
Signals
- GitHub stars
- 114
- Forks
- 31
- Last commit
- Sep 2026
Advanced
- Catalog kind
- skill
- Gateway key
dotnet-best-practices-vixenlights- Source
- github.com/vixenlights/vixen