Specification Business Rules Csharp.instructions
--- applyTo: '**/*Domain/**/*.cs' description: Guidelines for encapsulating business rules in aggregates using the Specification pattern (DDD, C#) --- # Business Rules Encapsulation in Aggregates ## Purpose Define how to properly encapsulate business rules and invariants within aggregates, establish clear criteria for when to use the Specification pattern versus direct implementation, and ensure business logic remains within the domain boundary following DDD principles. ## Business Rules Encapsulation - Always encapsulate business rules and invariants inside the aggregate root. - Use explicit business methods (not setters/getters) to enforce invariants. - Keep simple invariants directly in aggregate methods (e.g., quantity > 0, required fields). - The aggregate remains the single source of truth for business consistency. - Avoid leaking domain logic to application or infrastructure layers. ## When to Use Specification Pattern - Use Specification for **complex business rules** that involve multiple conditions or calculations. - Use Specification for **reusable rules** across different aggregates or contexts. - Use Specification for **combinable rules** that need logical operators (And, Or, Not). - Use Specification when business rules require **external data** or **cross-aggregate validation**. - **Prefer existing specification interfaces** from shared kernel or domain libraries before creating custom ones. - **Do not use** Specification for simple field validation or basic invariants. ## CRITICAL: Complete Implementation Requirements When implementing the Specification pattern, you MUST provide: ### 1. Complete Implementation Chain - ✅ The specification classes themselves (e.g., ActivePolicySpecification) - ✅ A concrete repository implementation showing `FindBySpecificationAsync()` usage - ✅ Actual usage in query handlers/use cases with specification instantiation - ✅ Usage examples demonstrating combinations (AND, OR, NOT) ### 2. Repository Integration - Repository MUST have `FindBySpecificationAsync(ISpecification<T> spec)` method - Show the actual filtering logic using `specification.IsSatisfiedBy(entity)` - Other specific methods SHOULD internally delegate to specifications: ```csharp public async Task<IReadOnlyCollection<Trip>> FindAvailableTripsForPeriodAsync( DateTime startDate, DateTime endDate, CancellationToken ct = default) { var spec = new TripAvailableInPeriodSpecification(startDate, endDate); return await FindBySpecificationAsync(spec, ct); } ``` ### 3. Query Handler / Use Case Usage Query handlers MUST explicitly instantiate and use specifications:
when to use it
Community prompt sourced from the open-source GitHub repo SebastienDegodez/copilot-instructions (Apache-2.0). A "Specification Business Rules Csharp.instructions" style prompt — adapt the placeholders and specifics to your task. Imported as-is and not independently retested here, so check the output before relying on it.
tags
roleplaycommunitygeneral
source
SebastienDegodez/copilot-instructions · Apache-2.0