Every team that adopts Clean Architecture draws the same diagram: domain in the center, application around it, infrastructure and presentation on the outside, dependencies pointing inward. And every team watches that diagram erode - a controller that reaches straight into a repository, a domain entity that suddenly knows about EF Core. The diagram has no teeth. NetArchTest gives it teeth by turning the rules into tests.
Rules that are documentation no one reads
The dependency rules of a layered architecture are simple to state: lower layers never reference upper layers, the domain depends on nothing, presentation never talks to persistence directly. The problem is enforcement. A rule that lives in a wiki or a senior engineer's memory is enforced inconsistently and silently violated under deadline pressure. By the time anyone notices, the violation is load-bearing.
Encoding the rules as tests
NetArchTest lets you assert these rules against your compiled assemblies. The API reads almost like the English version of the rule:
[TestMethod]
public void Domain_should_not_depend_on_other_layers()
{
var result = Types.InAssembly(DomainAssembly)
.Should()
.NotHaveDependencyOnAny("Acme.Application", "Acme.Infrastructure", "Acme.Web")
.GetResult();
result.IsSuccessful.Should().BeTrue(
$"domain must stay pure; offenders: {string.Join(", ", result.FailingTypeNames)}");
}
You can express the whole rule set this way: controllers must not depend on repositories, handlers must live in the application layer, anything implementing a repository interface must sit in infrastructure. Each becomes a test that names its violators when it fails.
The payoff: failures at review time
The value is in when the failure happens. These tests run in CI on every pull request, so an architectural violation fails the build the moment it is introduced - while the author still has the context, and before the bad dependency becomes something ten other files rely on. The cost of fixing a violation rises steeply with time; catching it at review time is when it is nearly free.
Tip: When an architecture test fails, the right question is not always "how do I make this pass?" Sometimes the rule is wrong and the code is right. The test failing forces that conversation deliberately, which is exactly what you want.
Keep the rules readable
Architecture tests are also living documentation - often the most accurate documentation of your architecture, because they cannot lie. Lean into that: name the tests after the rule they protect, write failure messages that explain the intent, and keep them in one obvious place so a new engineer can read the rule set as a description of how the system is meant to fit together.
Wrapping up
Clean Architecture only delivers its benefits if its rules are actually upheld, and humans uphold rules inconsistently. NetArchTest moves enforcement from intention to automation: encode each dependency rule as a test, run it in CI, and let the build fail the moment someone crosses a boundary. The diagram stops being a hopeful drawing and becomes a contract the code is checked against on every commit.
Want your architecture to stay clean as the team grows? Let's set it up.
