Architecture tests: Logiswift.Eos.ArchitectureTests
Enforces the modular-monolith layering rules (see Architecture Overview) in
CI, via NetArchTest.Rules
— a violation fails dotnet test the same as any other broken test, rather
than only being caught by code review. Lives in
tests/Logiswift.Eos.ArchitectureTests/, referencing every src/ project
(it only reads their assembly metadata, never calls into them).
What's covered
LayerDependencyTests.cs has one [Fact] per rule, so a break names the
specific rule rather than just "architecture test failed":
- Domain has zero project references and zero infrastructure packages (EF Core, SQL client, RabbitMQ, Redis, MailKit, Azure/Graph/Identity, ASP.NET Core).
- Application depends only on Domain and never on EF Core.
- Infrastructure never depends on Api/Api.External/Workers.
- The three composition roots never depend on each other.
- Controllers/jobs never depend on
Infrastructure.Persistence.Scaffoldeddirectly — the "never touch scaffolded entities directly" rule from the database-first conventions. - No module under
Infrastructure/Persistence/Repositories/{Auth,Automation, Com,Edi,Ext,Mas,Tms,Wms}depends on another module's repository namespace — this holds even inside one deployment unit, since it's exactly the boundary that has to already hold if a module is ever split into its own service later.
:::note Table-prefix groupings, not Application/Modules/ names
The module boundary this rule enforces is the table-prefix grouping under
Repositories/, not Application/Modules/'s names — the two don't line up
1:1. See Architecture Overview's "Modules" section.
:::
:::caution Composition-root checks use plain reflection, not HaveDependencyOn
Logiswift.Eos.Api is a string-prefix of Logiswift.Eos.Api.External —
NetArchTest matches dependency namespaces by prefix, so checking "Api.External
doesn't depend on Logiswift.Eos.Api" via NetArchTest self-matches every type
in Api.External's own Logiswift.Eos.Api.External.* namespace and
false-positives with no real dependency at all. The composition-root-vs-
composition-root checks use plain Assembly.GetReferencedAssemblies()
exact-name comparison instead. Every other rule above has no such name
collision and uses NetArchTest directly.
:::
What's not covered
[RepositoryWriteStrategy]/module-folder conventions, the Reference-CRUD-
pattern shape, and other structural (not layering) rules documented
elsewhere are still enforced by code review, not this project.
Reference files
tests/Logiswift.Eos.ArchitectureTests/LayerDependencyTests.cs.