.net conventions

Style & Formatting

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 ".net conventions" with this command: npx skills add exceptionless/exceptionless/exceptionless-exceptionless-net-conventions

.NET Conventions

Style & Formatting

  • Follow .editorconfig rules strictly

  • Run dotnet format before committing

  • Minimize diffs: Change only what's necessary, preserve existing formatting and structure

  • Match surrounding code style exactly

Naming Conventions

Element Convention Example

Private fields _camelCase

_organizationRepository

Public members PascalCase GetByIdAsync

Local variables camelCase organizationId

Constants PascalCase MaxRetryCount

Type parameters T prefix TModel

Formatting Rules

  • Indentation: 4 spaces, no tabs

  • Namespaces: File-scoped (namespace Foo; )

  • Usings: Outside namespace

  • Braces: Always use, even for single-line blocks

  • No #region : Never use #region /#endregion directives — they hide code and discourage refactoring

Async Patterns

  • Suffix: Always use Async suffix for async methods

  • CancellationToken: Pass through call chains when available

  • ValueTask: Prefer ValueTask<T> for hot paths that often complete synchronously

  • ConfigureAwait: Not required in ASP.NET Core

// From src/Exceptionless.Core/Services/UsageService.cs public async Task SavePendingUsageAsync() { var utcNow = _timeProvider.GetUtcNow().UtcDateTime; await SavePendingOrganizationUsageAsync(utcNow); await SavePendingProjectUsageAsync(utcNow); }

Structured Logging

Use message templates with named placeholders — values go in the args, not string interpolation:

// ✅ Correct: Named placeholders for structured data _logger.LogInformation("Saving org ({OrganizationId}-{OrganizationName}) event usage", organizationId, organization.Name);

_logger.LogError(ex, "Error retrieving event post payload: {Path}", path);

_logger.LogWarning("Unable to parse user agent {UserAgent}. Exception: {Message}", userAgent, ex.Message);

// ❌ Wrong: String interpolation loses structure _logger.LogInformation($"Saving org {organizationId}");

Log Scopes with ExceptionlessState

Use scopes to add context to all log entries within a block:

// From src/Exceptionless.Core/Jobs/EventPostsJob.cs using var _ = _logger.BeginScope(new ExceptionlessState() .Organization(ep.OrganizationId) .Project(ep.ProjectId));

// All log entries in this scope automatically include org/project context _logger.LogInformation("Processing event post");

Add tags and properties for richer context:

using (_logger.BeginScope(new ExceptionlessState() .Organization(organization.Id) .Tag("Delete") .Tag("Bot"))) { _logger.LogInformation("Removing bot events"); }

Nullable Reference Types

  • Honor nullable annotations throughout

  • Treat nullable warnings as errors

  • Use ? suffix for nullable types

public async Task<User?> FindUserAsync(string? email) { if (string.IsNullOrWhiteSpace(email)) return null;

return await _repository.FindByEmailAsync(email);

}

Resource Disposal

// Prefer using declarations using var stream = File.OpenRead(path);

// Async disposal await using var connection = await CreateConnectionAsync();

Constructor Injection

Prefer constructor injection with readonly fields:

// From src/Exceptionless.Core/Services/UsageService.cs public class UsageService { private readonly IOrganizationRepository _organizationRepository; private readonly ICacheClient _cache; private readonly TimeProvider _timeProvider; private readonly ILogger _logger;

public UsageService(
    IOrganizationRepository organizationRepository,
    ICacheClient cache,
    TimeProvider timeProvider,
    ILoggerFactory loggerFactory)
{
    _organizationRepository = organizationRepository;
    _cache = cache;
    _timeProvider = timeProvider;
    _logger = loggerFactory.CreateLogger&#x3C;UsageService>();
}

}

Validation Patterns

Input Validation

Validate early, fail fast:

public async Task<ActionResult> ProcessAsync(string id) { if (string.IsNullOrEmpty(id)) return BadRequest("Id is required");

var entity = await _repository.GetByIdAsync(id);
if (entity is null)
    return NotFound();

// Continue processing

}

Domain Validation

See backend-architecture for validation patterns (FluentValidation for domain models, MiniValidator for API requests).

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.

General

shadcn-svelte components

No summary provided by upstream source.

Repository SourceNeeds Review
General

tanstack-form

No summary provided by upstream source.

Repository SourceNeeds Review
General

stripe-best-practices

No summary provided by upstream source.

Repository SourceNeeds Review
General

frontend-design

No summary provided by upstream source.

Repository SourceNeeds Review