Repository Structure
Relevant source files
The following files were used as context for generating this wiki page:
The DDD & Event-Driven Architecture Learning Project is organized into a modular, multi-layered architecture designed to demonstrate Domain-Driven Design (DDD) principles and microservices integration. The structure separates cross-cutting concerns (BuildingBlocks), core business logic (Bounded Contexts), and various hosting or frontend implementations.
The repository utilizes .NET Aspire for orchestration, managing dependencies like RabbitMQ and SQL Server while coordinating multiple Web APIs and frontend applications. The architecture follows a strict separation between domain, application, infrastructure, and presentation layers to ensure testability and maintainability.
Sources: claude.md:1-25, claude.md:255-265
Architectural Layers
Building Blocks
The BuildingBlocks/ directory contains shared infrastructure and common domain abstractions used across all bounded contexts. This prevents code duplication and enforces consistent patterns for persistence, messaging, and authentication.
| Component | Description |
|---|---|
| Domain | Base entities, value objects, and domain event interfaces. |
| Application | CQRS behaviors, pipeline configurations, and shared interfaces. |
| Infrastructure.EfCore | Unit of Work implementation and base repositories. |
| Infrastructure.MassTransit | Event bus abstractions and integration event consumers. |
| WebApplications | Shared API filters, JSON configurations, and OpenAPI/Scalar setup. |
Sources: claude.md:144-152, BuildingBlocks.Infrastructure.EfCore/EfCoreUnitOfWork.cs:12-40
Core Bounded Contexts
Business logic is partitioned into Bounded Contexts within the Core/ directory. Each context is self-contained with its own domain model and persistence logic.
- Scheduling: Handles healthcare appointment scheduling, including Patient, Appointment, and Doctor aggregates.
- Billing: Manages financial aspects such as
BillingProfileaggregates.
Sources: claude.md:31-36, claude.md:154-166
Project Organization Diagram
The following diagram illustrates the relationship between the different layers and projects in the repository.
The diagram shows how .NET Aspire orchestrates the APIs, which in turn utilize specific Bounded Contexts built upon shared Building Blocks.
Sources: claude.md:144-175, claude.md:240-250
Infrastructure and Tooling
.NET Aspire & Worktree Slots
The project implements a "Worktree Slot" system to allow multiple developers or agents to work in parallel on the same machine without port or database conflicts. Ports and database names are derived based on a slot ID (1-5).
- Slot 1: Default/Main checkout.
- Slots 2-5: Secondary worktrees with offset ports (e.g., base + 100).
Sources: Aspire.AppHost/WorktreeSlot.cs:11-30, claude.md:173-174
Development Scripts
A variety of PowerShell scripts manage the development environment and CI/CD readiness.
The build process integrates with ensure-docker.ps1 to prevent hanging during compilation if Docker is not running.
Sources: scripts/DOCKER_AUTOSTART_FIX.md:10-50, scripts/worktree-init.ps1:1-20
Frontend Architecture
The project currently supports an Angular-based frontend, with a deferred Blazor track. The Angular application uses modern signals and standalone components.
- Path:
Frontend/Angular/Scheduling.AngularApp/ - Key Tech: Angular 21, Signals, Zoneless change detection, Angular Material.
- Security: BFF (Backend-for-Frontend) pattern where the SPA uses cookies and never handles tokens directly.
Sources: claude.md:88-102, Frontend/Angular/Scheduling.AngularApp/package.json:20-35
Testing Infrastructure
The repository enforces a two-tier test hierarchy via BuildingBlocks.Tests to ensure consistency.
- ValidatorTestBase: For FluentValidation unit tests with mocked dependencies.
- TestBase: For integration tests using SQLite in-memory and real
UnitOfWorkimplementations.
Sources: claude.md:58-65, BuildingBlocks/BuildingBlocks.Tests/TestBase.cs:18-45
Database Isolation in Tests
Tests use transaction-based isolation. Each test starts a transaction that is rolled back during cleanup to maintain a pristine state for subsequent tests.
This sequence ensures that data changes in one test do not persist and affect other tests.
Sources: BuildingBlocks/BuildingBlocks.Tests/TestBase.cs:64-85, BuildingBlocks/BuildingBlocks.Infrastructure.EfCore/EfCoreUnitOfWork.cs:118-145
Conclusion
The repository structure is a blueprint for scalable .NET microservices. By leveraging .NET Aspire for orchestration and shared "Building Blocks" for architectural consistency, the project maintains a clear separation of concerns. This organization facilitates both individual development through worktree slots and complex integration testing through standardized base classes and in-memory database isolation.