dotnet-domain-modeling

Implements immutable C# domain models with sealed records, guards, and pure-domain TDD.

2|Updated Jul 18, 2026
One-click install
npx skills add https://github.com/Arasz/ai-badger --skill dotnet-domain-modeling-arasz
Or copy as Structured Prompt for Agent
Please help me install this Agent Skill.
Skill: dotnet-domain-modeling
Source: https://github.com/Arasz/ai-badger/tree/main/features/dotnet/skills/dotnet-workload/references/dotnet-domain-modeling
Command: npx skills add https://github.com/Arasz/ai-badger --skill dotnet-domain-modeling-arasz

SYSTEM DOCUMENTATION & REQUIREMENTS

💡 This Skill includes references (resource) components.

What problem does it solve? Designing a pure .NET domain layer is error-prone: records that mutate state, guard clauses with hidden generic constraints, validators that drift from constructors, and infrastructure dependencies leaking into domain code. This Skill provides concrete patterns and tested conventions for building immutable C# domain models that stay clean and verifiable. ## Core Features & Use Cases - Immutable Record Pattern: Sealed records with required/init properties, state-transition methods returning new instances via with expressions, and CommunityToolkit.Diagnostics guards (including the Guard.IsEqualTo notnull/IEquatable pitfalls and fixes). - Policy Objects & State Machines: Standalone policy classes for multi-input decisions, lifecycle transition matrices, and Default Interface Methods for evolving extension-point interfaces without breaking implementors. - Domain Purity & Testing: ArchUnitNET rules blocking infrastructure namespaces, FluentValidation nested validators, TDD workflows, Cosmos persistence patterns (encrypted documents, optimistic concurrency, wildcard-ETag upserts), and Durable Functions orchestration guidance. - Use Case: When adding a new aggregate to a Clean Architecture .NET solution — for example a case-management entity with status transitions — use this Skill to scaffold the record, guards, policy, repository interface, contract tests, and Cosmos adapter in the correct order. ## Quick Start Ask the agent to model a new C# domain aggregate with immutable records, guard clauses, and a state machine following the dotnet-domain-modeling conventions.

Frequently Asked Questions about dotnet-domain-modeling

High-intent search queries and answers about installing and using this skill.

FAQPage Schema
How do I model immutable domain entities in C#?

Use sealed records with required and init-only properties, and implement state transitions as methods that return a new instance via `this with { ... }` rather than mutating. Guard invalid transitions at method entry with ThrowHelper or Guard calls.

Why does Guard.IsEqualTo fail to compile with enums or nullable types?

Guard.IsEqualTo<T> constrains T to notnull and IEquatable<T>, so nullable references produce CS8714 and enums produce CS0315. Replace it with an explicit `if` check plus ThrowHelper.ThrowInvalidOperationException.

How do I enforce domain layer purity in .NET?

Use ArchUnitNET to write an architecture test asserting that types in the domain assembly do not depend on infrastructure namespaces such as Azure, EntityFrameworkCore, or System.Net.Http. The test fails the build when a forbidden dependency appears.

Should I keep null-guard checks on constructor parameters with nullable reference types enabled?

For internal types constructed only by DI inside one nullable-enabled assembly, ctor null guards are dead code and can be removed. Keep them on public API boundaries, since deserialization, reflection, and #nullable disable callers can still pass null at runtime.

How do I add a method to an interface without breaking existing implementations?

Use a Default Interface Method: add the new member with a default body (for example returning null) so existing implementors keep working unchanged. Callers try the new method first and fall back to the old contract when the default is returned.

When should domain decision logic move into a policy object?

Extract a standalone sealed policy class when a decision depends on multiple inputs such as aggregate state, signal classification, and confidence thresholds, and is too complex for a single transition method. The policy returns a decision record rather than mutating the aggregate.