4. Solution Strategy

April 11, 2026 · View on GitHub

4.1 Technology Decisions

DecisionRationale
Microservices architectureDemonstrates decomposition, independent deployability, per-service data ownership, and eventual consistency. See ADR-0001.
.NET / ASP.NET CoreAuthor's expertise; single-stack keeps the solution accessible to .NET developers. See ADR-0002.
RabbitMQPush-based event notification with queue semantics; simpler than Kafka for the educational scope. See ADR-0003.
SQL ServerSingle database platform avoids polyglot-persistence complexity. See ADR-0007.
Docker / KubernetesContainerisation is the standard deployment model. Kubernetes manifests enable orchestration demos. See ADR-0010.

4.2 Architectural Patterns & Approaches

PatternWhere AppliedPurpose
Event-Driven ArchitectureAll servicesServices communicate asynchronously through domain events published to RabbitMQ. This decouples services and enables eventual consistency.
Domain-Driven Design (DDD)WorkshopManagementAPIThe core bounded context uses Aggregates (WorkshopPlanning), value objects, and domain events to model complex business rules.
Event SourcingWorkshopManagementAPIThe WorkshopPlanning aggregate persists its state as a sequence of domain events in a dedicated event store, rather than as current-state snapshots. See ADR-0004.
CQRSWorkshopManagementAPICommands are transformed into events that modify the aggregate; a separate read-model is built by the WorkshopManagementEventHandler for query purposes.
CRUDCustomerManagementAPI, VehicleManagementAPISupporting bounded contexts with simple lifecycle; Entity Framework Core with code-first migrations.
Messaging AbstractionInfrastructure.Messaging libraryIMessagePublisher and IMessageHandler interfaces decouple all services from the concrete broker implementation. See ADR-0009.

4.3 Key Design Decisions

  1. Different design approaches per bounded context — Workshop Management (core domain) uses DDD + event sourcing; Customer and Vehicle Management (supporting domains) use simple CRUD. This demonstrates that different services warrant different levels of design complexity.

  2. Dedicated Time Service — Rather than using internal timers or cron jobs, a dedicated service publishes DayHasPassed events. This makes time-dependent behaviour fully deterministic and testable. See ADR-0005.

  3. No API Gateway — The WebApp calls backend APIs directly using Refit typed HTTP clients. This keeps the solution focused on core microservices patterns. See ADR-0006.

  4. Centralized logging with Seq — All services use Serilog for structured logging and send log events to a central Seq server. This provides a single pane of glass for observability. See ADR-0008.

  5. Read-model in Workshop Management — The WorkshopManagementEventHandler builds a read-model with cached Customer and Vehicle data. This ensures Workshop Management can operate autonomously even when other services are offline.


← Back to arc42 index