The first law of distributed systems is do not distribute unless you must. Over the past decade of enterprise software engineering, countless engineering teams succumbed to “microservices hype”: systems operated by modest teams were prematurely fragmented into dozens of isolated network services, introducing distributed transaction failures, non-deterministic latency spikes, cascading dependency outages, and runaway cloud infrastructure overhead.
Yet retreating to the traditional “three-tier layered monolith” presents equally hazardous traps: bloated controllers, business rules scattered across opaque service classes, and tangled cross-domain database foreign keys that inevitably degrade into an unmaintainable “Big Ball of Mud.”
BitzOrcas.Modern is engineered to reconcile this architectural dichotomy. Designed as an enterprise-grade modular monolith foundation on .NET 10 LTS and C# 14, it couples strict physical boundary governance (ArchUnitNET), Vertical Slice Architecture, and zero-reflection compile-time Source Generators to deliver the frictionless development velocity of a single process alongside the hard isolation boundaries of microservices.
Core Architectural Topology
The system hierarchy strictly adheres to unidirectional dependency rules. The underlying infrastructure and Roslyn generators deliver a zero-reflection runtime to application domains:
The End-to-End Request Lifecycle
In BitzOrcas.Modern, mutating commands and complex queries never execute uninspected inside Minimal API route handlers. Requests are encapsulated as strongly-typed Mediator commands and must traverse the framework-governed 10-tier linear execution pipeline:
Core Architectural Principles & Trade-offs
1. Vertical Slice Architecture
Conventional enterprise architectures organize code horizontally across technical concerns:
Controllers/ ──> Services/ ──> Repositories/ ──> Entities/When an engineering team needs to introduce a validation rule to a legal matter conflict check, developers must modify ConflictController, IConflictService, ConflictService, ConflictDto, ConflictMapper, and ConflictEntity. This excessive indirection creates severe cognitive overhead.
BitzOrcas replaces this horizontal partitioning with self-contained vertical slices centered on discrete use cases:
src/Platform/Identity/BitzOrcas.Identity.Application/Commands/Login/├── Login.cs # Minimal API route binding + Mediator Command contract├── LoginHandler.cs # Pure domain orchestration logic├── LoginRequestRule.cs # Strongly typed static invariant validation (Tier 1)└── LoginResult.cs # Strongly typed return model (no bloated envelopes)- High Cohesion: Business logic modifications are isolated to a single folder, preventing merge conflicts across concurrent teams.
- Self-Healing Refactoring: Retiring a feature requires deleting a single slice folder without stranding orphaned interface implementations across shared libraries.
2. 10-Tier Application Execution Pipeline
The framework offloads enterprise non-functional concerns to the pipeline. Every behavior executes in deterministic order to keep business handlers clean and focused:
| Order | Pipeline Behavior | Core Responsibility | Short-Circuit Semantics |
|---|---|---|---|
| 01 | LoggingPipelineBehavior | Binds traceparent, calculates request execution duration | Always transparent; captures full stack traces upon unhandled faults |
| 02 | RuntimeLicensePipelineBehavior | Validates signed commercial certificates and tenant seats | Halts execution immediately on expired license, returning 403 Forbidden |
| 03 | DelegatedSessionRestrictionPipelineBehavior | Enforces sandboxing on support/operator impersonation sessions | Blocks unauthorized mutation attempts, returning 403 Forbidden |
| 04 | AuthorizationPipelineBehavior | Evaluates declarative RBAC / ABAC / ReBAC policies | Rejects unauthorized actors, returning 403 Forbidden |
| 05 | ValidationPipelineBehavior | Executes IRequestRule and tenant dynamic rules | Aborts on invariant violation, returning 400 Bad Request |
| 06 | IdempotencyPipelineBehavior | Evaluates Idempotency-Key and Redis distributed lock | Serves cached payload directly on duplicate submissions |
| 07 | TransactionPipelineBehavior | Automatically scopes and commits atomic database transactions | Automatically issues Rollback on exceptions to preserve data integrity |
| 08 | DomainEventDispatchPipelineBehavior | Dispatches domain events and flushes CAP Outbox records | Commits within the local database transaction for at-least-once delivery |
| 09 | ActivityAuditPipelineBehavior | Extracts entity state diffs and serializes structured audit records | Flushes asynchronously post-commit without adding latency to the client |
| 10 | ReadModelDisplayPipelineBehavior | Hydrates dictionaries and localized strings on Query results | Active only for read pipelines; leverages zero-reflection projections |
3. Unified Aggregate Roots with Dual ORM Generation
Traditional architectures mandate duplicate classes for DomainModel and DatabaseEntity, requiring hundreds of fragile mapping profiles.
In BitzOrcas.Modern, across 95% of standard scenarios, the domain aggregate root is the persistence model (Unified Aggregate Root):
- Aggregates inherit from
Entity<TId>orAggregateRoot<TId>with strongly typed IDs (e.g.,UserId,MatterId). - Annotated with vendor-neutral Fluent mapping metadata, Roslyn incremental source generators synthesize high-performance static bindings at compile time.
- Dual Production Adapters: SqlSugar serves as the high-throughput primary adapter alongside EF Core as an equal production adapter. Application layers interact solely through
IEntitySet<TAggregate>, preventing leaky ORM dependencies.
Cross-Module Collaboration Rules
To ensure a growing modular monolith does not degenerate into a tangled dependency graph, cross-module communication is governed by five non-negotiable physical rules:
- Unidirectional Contract Dependencies: Module A may only reference the target module’s contract package (
*.Contracts). Direct references to another module’sApplication,Domain, orInfrastructureassemblies are prohibited. - Read Queries via Read-Only Ports: When Module A requires data owned by Module B, it must call an explicit read-only query service exposed in
*.Contracts(e.g.,IUserLookupService). Injecting foreignIEntitySet<T>abstractions across module boundaries is forbidden. - State Mutations via Commands or Async Events: Cross-module business actions must be coordinated asynchronously via CAP Transactional Outbox integration events or dispatched as explicit Mediator commands.
- Domain Events Remain Module-Internal: Events emitted via
AddDomainEvent()are scoped strictly to the originating aggregate and dispatched within the same process transaction. Cross-module side effects must be translated into explicit Integration Events. - Schema and Table Boundary Isolation: Each module maintains isolated table prefixes or database schemas. Writing raw SQL queries that execute cross-module
JOINoperations is strictly prohibited.
Architectural Glossary
| Term | English | Definition & Architectural Scope |
|---|---|---|
| Modular Monolith | Modular Monolith | Highly cohesive, weakly coupled domains packaged within a single deployable .NET solution. Physical boundaries are continuously enforced via ArchUnitNET automated fitness functions. |
| Vertical Slice | Vertical Slice | Structuring code by autonomous business use cases (route + command + rule + handler + response), discarding horizontal technical layering. |
| Unified Aggregate Root | Unified Aggregate Root | The core DDD aggregate encapsulating business invariants and domain event generation, decorated with persistence metadata to eliminate redundant DTO mappings. |
| 10-Tier Application Pipeline | 10-Tier Application Pipeline | A linear Mediator chain of responsibility that transparently enforces logging, licensing, impersonation, authorization, validation, idempotency, transactions, and auditing. |
| 4-Tier Business Validation | 4-Tier Business Validation | A structured validation hierarchy: Universal Invariant Rules (Tier 1), Composite Code Strategies (Tier 2A), Tenant Hot-Config Strategies (Tier 2B), and No-Code Field Rules (Tier 3). |
| Transactional Outbox | Transactional Outbox | A pattern ensuring business entity mutations and integration messages are written atomically in a single local database transaction before background relay to RabbitMQ. |
| Impersonation | Impersonation | A privilege delegation model allowing support engineers to assume a tenant user identity under strict audit trails and mutation sandboxing. |
| Native AOT | Ahead-of-Time Compilation | Compiling .NET 10 C# assemblies directly into native machine code, eliminating JIT overhead and runtime reflection for sub-second container cold starts. |
Repository Directory Blueprint
In /Users/linxinyu/Git/Repos/Codeup/BitzOrcasVNext, source code is partitioned across clean engineering boundaries:
src/├── Framework/ # Zero-dependency foundational technical kernel│ ├── BitzOrcas.Application/ # 10-tier pipeline behaviors, validation rules, authorization abstractions│ ├── BitzOrcas.Domain/ # Entity primitives, aggregate roots, Result/Error types│ ├── BitzOrcas.Persistence/ # Dual persistence adapters (SqlSugar / EF Core) and metadata│ └── BitzOrcas.Workflow/ # Proprietary lightweight DAG state machine workflow engine├── Platform/ # Commercial platform capabilities (distributed as private packages)│ ├── Identity/ # Multi-tenancy, authentication, 2FA, external SSO, password encryption│ ├── Authorization/ # Unified RBAC, ABAC, and ReBAC Lite policy decision engine│ ├── Auditing/ # Enterprise activity logging, entity state diff capture, and envelopes│ ├── Files/ # Object storage abstractions, chunked uploads, asset lifecycles│ └── Notifications/ # Multi-channel notification dispatch (email, SMS, in-app)├── Hosts/ # Entry points and composition roots│ ├── BitzOrcas.Api/ # Primary Minimal API host wiring all module routes│ ├── BitzOrcas.Gateway/ # YARP edge reverse proxy and traffic router│ └── BitzOrcas.JobHost/ # Quartz.NET job host managing tenant scheduled workflows└── Tooling/ # Developer tooling and automation ├── BitzOrcas.Cli/ # Official CLI scaffolder for generating vertical slices and modules └── BitzOrcas.Generators/ # Roslyn incremental source generators for zero-reflection wiringThis rigorous architecture equips engineering teams with rapid daily development velocity in a unified codebase while preserving the structural freedom to extract isolated microservices whenever business scale requires.