February 17 2026
Sponsored
Today's issue is sponsored by Packt. Working with React doesn't have to be complex. "React 18 Design Patterns and Best Practices" empowers you to harness React's potential, making your applications flexible, easy to manage, and high-performing. Discover and unravel the dynamic features of React 18 and Node 19. This updated fourth edition equips you with insights into the cutting-edge tools that will elevate your projects. Book Link
Many thanks to the sponsors who make it possible for this newsletter to be free for readers. Become a sponsor.
Most teams don’t break their architecture in one dramatic moment.
They break it one small reference at a time.
A developer adds a quick dependency. A service references Infrastructure directly. A Controller talks to DbContext. A helper leaks into the wrong layer.
And suddenly, your "Clean Architecture" is just a folder structure.
If you are working in:
• ASP.NET Core APIs • Microservices • Modular Monoliths • Enterprise .NET applications
You need a way to automatically enforce architecture rules.
That’s where Architecture Tests in .NET come in.
Architecture tests in .NET are automated tests that validate architectural rules such as layer boundaries and assembly dependencies. Architecture tests are automated tests that validate:
• Layer dependencies • Namespace boundaries • Naming conventions • Assembly references • Clean Architecture rules
Instead of relying on code reviews to catch architectural violations, you let tests fail when someone breaks your design.
In the .NET ecosystem, one of the most powerful tools for this is:
👉 NetArchTest
Let’s talk real-world scenario.
Imagine this structure:
• MyApp.Domain • MyApp.Application • MyApp.Infrastructure • MyApp.API
Clean Architecture rule:
Domain must not depend on Infrastructure.
But nothing stops a developer from accidentally adding:
using MyApp.Infrastructure;
Now your Domain layer depends on Infrastructure.
Architecture broken.
Without architecture tests, you may not even notice this for weeks.
With architecture tests?
The build fails immediately.
Add the NuGet package to your test project:
dotnet add package NetArchTest.Rules
Or via Visual Studio Package Manager.
Now we can start writing automated architecture validation tests.
Let’s enforce this rule:
The Domain layer must not reference Infrastructure.
using NetArchTest.Rules;using Xunit; public class ArchitectureTests{ [Fact] public void Domain_Should_Not_Depend_On_Infrastructure() { var result = Types .InAssembly(typeof(DomainMarker).Assembly) .ShouldNot() .HaveDependencyOn("MyApp.Infrastructure") .GetResult(); Assert.True(result.IsSuccessful); }}
Let’s break this down:
• Types.InAssembly(...) - Loads all types from the Domain assembly.
• .ShouldNot().HaveDependencyOn(...) - Defines the architectural rule.
• .GetResult() - Executes the rule validation.
• Assert.True(result.IsSuccessful) - Fails the test if any violation is found.
Now your architecture is enforced automatically.
Here’s a more advanced rule:
Application layer must not depend on API layer.
[Fact]public void Application_Should_Not_Depend_On_API(){ var result = Types .InAssembly(typeof(ApplicationMarker).Assembly) .ShouldNot() .HaveDependencyOn("MyApp.API") .GetResult(); Assert.True(result.IsSuccessful);}
This ensures:
• No accidental circular dependencies • No UI leakage into core logic • Proper separation of concerns
You can even enforce naming rules. Example: All services must end with "Service".
[Fact]public void Services_Should_End_With_Service(){ var result = Types .InAssembly(typeof(ApplicationMarker).Assembly) .That() .AreClasses() .And() .HaveNameEndingWith("Service") .Should() .BePublic() .GetResult(); Assert.True(result.IsSuccessful);}
This helps keep your project consistent and predictable.
In large enterprise systems: • 10+ projects • Multiple teams • Microservices • Shared libraries
Architecture drift happens constantly.
When I worked on enterprise systems, we had situations where: • Infrastructure leaked into Domain • DTOs were referenced in Core • Controllers called EF Core directly
After introducing architecture tests:
• Violations were caught immediately • Code reviews became easier • Refactoring was safer • New developers onboarded faster
Architecture tests became part of CI.
That’s when architecture stopped being documentation and became enforcement.
The real power comes when you run architecture tests in:
• GitHub Actions • Azure DevOps • GitLab CI • Any .NET CI pipeline
If someone breaks architecture:
❌ The pipeline fails.
Now architecture is not optional.
It’s enforced.
Use them if you:
• Follow Clean Architecture • Use Onion Architecture • Build Modular Monoliths • Maintain Microservices • Work in large teams • Want to prevent architectural erosion If your project has more than 2 layers, you should consider them mandatory.
Clean Architecture in .NET is not about having four projects named Domain, Application, Infrastructure, and API.
It’s about enforced boundaries.
Architecture tests transform architectural discipline from a human process into an automated guarantee. Instead of hoping developers remember rules, your CI pipeline enforces them. Instead of relying on code reviews to catch structural violations, your tests fail immediately.
That’s the difference between documentation and enforcement.
In real-world enterprise .NET systems - especially modular monoliths and microservices — architectural erosion doesn’t happen dramatically. It happens slowly. One dependency at a time. One “quick fix” at a time.
Architecture tests stop that.
They give you:
• Automated architecture validation • Safer refactoring • Long-term maintainability • Stronger CI enforcement • Predictable, scalable codebases
If you're serious about building production-grade .NET systems, architecture rules must be executable - not optional. In short
Architecture tests in .NET allow teams to automatically enforce Clean Architecture rules, prevent dependency violations, and integrate architectural validation into CI pipelines.
Architecture tests are just one part of a larger discipline: automated code quality enforcement in .NET.
In my course Pragmatic .NET Code Rules, I go deeper into:
• Enforcing Clean Architecture rules • CI/CD code quality automation • .editorconfig strategies • Analyzer configuration • Warnings-as-errors setup • Building self-cleaning .NET solutions • Preventing architectural drift in real production systems
The goal isn’t just clean code.
The goal is a predictable, enforceable, self-protecting codebase.
If you want your .NET projects to scale without turning into technical debt machines, this is exactly what the course is built for.
You can learn more here: 👉 Pragmatic .NET Code Rules That's all from me today.
Stop arguing about code style. In this course you get a production-proven setup with analyzers, CI quality gates, and architecture tests — the exact system I use in real projects. Join here.
Not sure yet? Grab the free Starter Kit — a drop-in setup with the essentials from Module 01.
Design Patterns that Deliver — Solve real problems with 5 battle-tested patterns (Builder, Decorator, Strategy, Adapter, Mediator) using practical, real-world examples. Trusted by 650+ developers.
Just getting started? Design Patterns Simplified covers 10 essential patterns in a beginner-friendly, 30-page guide for just $9.95.
Every Monday morning, I share 1 actionable tip on C#, .NET & Architecture that you can use right away. Join here.
Join 20,000+ subscribers who mass-improve their .NET skills with actionable tips on C#, Architecture & Best Practices.
Subscribe to the TheCodeMan.net and be among the 20,000+ subscribers gaining practical tips and resources to enhance your .NET expertise.