Skip to content

Architecture Rules

As a team grows, Specification naming becomes inconsistent. Someone names it ActiveProductSpec, while another creates IsActiveSpecification. Folder locations are all over the place. This chapter covers naming conventions, folder placement, and automated verification with ArchUnitNET to maintain consistency across the entire team.

  1. Naming conventions - Consistent naming in the {Aggregate}{Condition}Spec format
  2. Folder placement rules - Placing Specifications in a Specifications/ folder under the Aggregate
  3. ArchUnitNET verification - Automated rule verification through architecture tests

Naming Convention: {Aggregate}{Condition}Spec

Section titled “Naming Convention: {Aggregate}{Condition}Spec”

Specification names are composed by combining the target Aggregate and the condition.

SpecificationAggregateConditionDescription
ProductInStockSpecProductInStockProducts in stock
ProductPriceRangeSpecProductPriceRangeProducts within a price range
ProductLowStockSpecProductLowStockProducts with low stock
Domain/AggregateRoots/Products/
├── Product.cs
└── Specifications/
├── ProductInStockSpec.cs
├── ProductPriceRangeSpec.cs
└── ProductLowStockSpec.cs

ArchUnitNET is a library that verifies code architecture rules as tests.

// Classes in the Specifications namespace must end with Spec
var rule = Classes()
.That()
.ResideInNamespace("Specifications", useRegularExpressions: false)
.Should()
.HaveNameEndingWith("Spec");
rule.Check(Architecture);
ArchitectureRules/
├── Domain/
│ └── AggregateRoots/
│ └── Products/
│ ├── Product.cs
│ └── Specifications/
│ ├── ProductInStockSpec.cs
│ ├── ProductPriceRangeSpec.cs
│ └── ProductLowStockSpec.cs
└── Program.cs
ArchitectureRules.Tests.Unit/
├── SpecificationNamingTests.cs # ArchUnitNET architecture tests
└── ProductSpecTests.cs # Spec self-tests
RuleDescriptionVerification Method
Naming{Aggregate}{Condition}SpecArchUnitNET: HaveNameEndingWith("Spec")
PlacementSpecifications/ namespaceArchUnitNET: ResideInNamespace("Specifications")
Access restrictionsealed classCode review
Single responsibilityOne Spec = one conditionCode review
Rule DirectionMeaningProblem it prevents
Specifications -> SpecClasses in the namespace end with SpecUnrelated classes placed in the namespace
Spec -> SpecificationsClasses ending with Spec are in the namespaceSpecs placed in wrong locations

A: ArchUnitNET is a library that verifies architecture rules of .NET projects as unit tests. Inspired by Java’s ArchUnit, it defines rules with a Fluent API and verifies them with Check().

A: Code review alone cannot guarantee 100% compliance with naming conventions or folder placement rules. Including architecture tests in the CI/CD pipeline automatically detects rule violations, maintaining consistency.

Q3: Can the same rules be applied to Specifications of other Aggregates?

Section titled “Q3: Can the same rules be applied to Specifications of other Aggregates?”

A: Yes, ArchUnitNET rules are applied to the entire assembly. Even if you add CustomerEmailUniqueSpec to the Customer Aggregate, the same rules are automatically verified.

Q4: Does Functorium provide built-in architecture rules?

Section titled “Q4: Does Functorium provide built-in architecture rules?”

A: Yes. By inheriting DomainArchitectureTestSuite from Functorium.Testing, you get 3 Specification-specific rules out of the box:

RuleWhat it verifies
Specification_ShouldBe_PublicSealed()Enforces public sealed class
Specification_ShouldInherit_SpecificationBase()Enforces Specification<T> inheritance
Specification_ShouldResideIn_DomainLayer()Enforces placement in domain namespace

In real projects, you simply inherit this suite and define only additional rules. The rules written by hand in this chapter are for understanding the principles of ArchUnitNET.


In Part 4, we explored real-world usage of the Specification pattern — CQRS integration, dynamic filter builders, testing strategies, and architecture rules. In Part 5, we’ll synthesize everything and apply it to actual domain scenarios.

Part 5, Chapter 1: E-Commerce Product Filtering