Documentation branch: docs/rc-1.0.2 Technical branch: release/rc-1.0.2 Scope: - Technical changed files: 13 - Technical changed C# files: 2 - Curated review markers: 33 - Kept review markers before apply: 32 - Removed false positives during curation: 1 Applied review files: - adas-core.Infrastructure/Repositories/MasterListRepository.cs Generated by n8n IEC 62304 documentation workflow.
adas-core.Infrastructure — Persistence & Communication Layer
The Infrastructure Layer of the ADAS Core platform.
Contains concrete implementations of repository contracts, MongoDB mapping configurations, message-bus integrations (RabbitMQ via EasyNetQ), Redis connectivity, and migration tooling. This layer translates between the Domain layer and external resources — databases, caches, and messaging brokers.
Table of Contents
- Overview
- Responsibilities
- Project Structure
- Dependencies
- MongoDB Repositories
- MongoDB Class Maps
- MongoDB Migrations
- Messaging (RabbitMQ / EasyNetQ)
- Redis Integration
- Infrastructure Utilities
- Design Rules
Overview
adas-core.Infrastructure implements the technical capabilities required by the Application and Domain layers. It is the only layer that knows about MongoDB, Redis, and RabbitMQ. Every interaction with external systems flows through this project, isolating the rest of the codebase from vendor-specific APIs.
Key characteristics:
- Implements Contracts — Satisfies every interface defined in
adas-core.Application.Repositories/Interfaces. - Persistence Ignorance for Domain — Domain entities remain POCOs; class-map contributors in
Utils/MongoMaps/configure BSON serialization externally. - Message-Bus Abstraction — RabbitMQ producer/consumer logic is abstracted behind Application-layer contracts while the concrete wiring lives here.
- Migration Tooling — MongoDB schema evolution scripts are versioned and executed by
MongoMigrations.Core. - Host Builder Extensions — Provides
MongoDbHostBuilderExtensionandCacheHostBuilderExtensionfor streamlined Host startup registration.
Responsibilities
| Concern | What this project does |
|---|---|
| Repository Implementation | Concrete classes for ~40 MongoDB-backed repositories (CRUD, aggregate queries, archive operations). |
| MongoDB Class Mapping | MongoMaps contributors register BSON discriminators, conventions, and property mappings. |
| Database Migrations | Versioned migration scripts that evolve the MongoDB schema without downtime. |
| Message Publishing | PublisherService dispatches domain events through RabbitMQ via EasyNetQ. |
| Message Receiving | ReceiverService subscribes to inbound queues and routes messages to Application-layer handlers. |
| Alert Dispatch | SendAlertService delivers system alerts to external notification channels. |
| Relay Integration | RelayService communicates with physical relay hardware. |
| Host Builder Extensions | Convenience helpers for wiring MongoDB and Redis into the ASP.NET Core host. |
| Custom BSON Converters | Entity-specific serialization logic registered with the MongoDB driver. |
Project Structure
adas-core.Infrastructure/
├── Repositories/ # ~40 concrete MongoDB repository implementations
│ ├── MongoRepository.cs # Generic base repository
│ ├── UserRepository.cs / PatientRepository.cs
│ ├── AdmissionRepository.cs / DischargeRepository.cs
│ ├── ObservationRepository.cs / ObservationArchiveRepository.cs
│ ├── TreatmentRepository.cs / TreatmentArchiveRepository.cs
│ ├── DiagnosisRepository.cs / DiagnosisArchiveRepository.cs
│ ├── AlarmRepository.cs / DeviceRepository.cs / CameraRepository.cs
│ ├── LightBeaconRepository.cs / RelayRepository.cs
│ ├── PumpStateRepository.cs / PumpObservationRepository.cs
│ ├── PumpArchiveRepository.cs / PumpAlarmEventRepository.cs
│ ├── PumpAlarmStateRepository.cs
│ ├── RecordingAlertRepository.cs / RecordingAlertArchiveRepository.cs
│ ├── DisplayRepository.cs / DisplayConfigRepository.cs
│ ├── DisplayCardConfigRepository.cs / DisplayChartConfigRepository.cs
│ ├── DisplayDetailConfigRepository.cs
│ ├── ConfigObservationRepository.cs
│ ├── ConfigPumpsRepository.cs / ConfigUnitsRepository.cs
│ ├── PointOfCareRepository.cs / PoCMappingRepository.cs
│ ├── PoCSettingsRepository.cs / UnitRepository.cs / SectionRepository.cs
│ ├── NoticeRepository.cs / ServiceConfigRepository.cs
│ ├── MasterListRepository.cs / MedicineRepository.cs
│ ├── PatientCarePlanRepository.cs / ArchivePatientCarePlanRepository.cs
│ ├── AppointmentRepository.cs / AppointmentArchiveRepository.cs
│ ├── PatientArchiveRepository.cs / AuthorityRepository.cs
│ └── HistoricalConfigChangesRepository.cs
│
├── Services/ # Infrastructure-level services
│ ├── PublisherService.cs # RabbitMQ outbound publishing via EasyNetQ
│ ├── ReceiverService.cs # RabbitMQ inbound subscription via EasyNetQ
│ ├── SendAlertService.cs # Alert delivery to external channels
│ └── RelayService.cs # Physical relay communication
│
├── Utils/ # Infrastructure helpers and extensions
│ ├── MongoDbHostBuilderExtension.cs
│ ├── CacheHostBuilderExtension.cs
│ ├── MongoUtils.cs
│ ├── TypesUtils.cs
│ ├── RabbitConsumerErrorStrategy.cs
│ ├── RabbitIErrorMessageSerializer.cs
│ ├── PatientObservationConverter.cs
│ ├── PatientObservationAlarmConverter.cs
│ ├── PatientPumpObservationConverter.cs
│ ├── PersonConverter.cs
│ ├── CustomPointOfCareConverter.cs
│ └── MongoMaps/ # ~30 BSON class-map contributors
│ ├── IEntityMapContributor.cs
│ ├── PatientMapContributor.cs / UserMapContributor.cs
│ ├── ObservationMapContributor.cs / AlarmMapContributor.cs
│ ├── DeviceMapContributor.cs
│ ├── DisplayMapContributor.cs / DisplayHomeConfigContributor.cs
│ ├── CardMapContributor.cs / CellMapContributor.cs / RowMapContributor.cs
│ ├── ColorConfigMapContributor.cs / HeaderMapContributor.cs
│ ├── GraphMapContributor.cs / FormMapContributor.cs
│ ├── BannerConfigMapContributor.cs / BoxConfigMapContributor.cs
│ ├── ComunicationFlowMapContributor.cs / CameraContributor.cs
│ ├── BeaconMapContributor.cs / PumpMapContributor.cs
│ ├── RelayContributor.cs / UnitMapContributor.cs / SectionMapContributor.cs
│ ├── PoCMapContributor.cs / ObsUnitMapContributor.cs
│ ├── MasterListMapContributor.cs / NoticeControlMapContributor.cs
│ ├── ServiceConfigMapContributor.cs / StandardMapContributor.cs
│ └── TreatmentMapContributor.cs / AppointmentMapContributor.cs / AuthMapContributor.cs
│
└── Migrations/
└── MongoMigrations/ # Schema evolution scripts
├── U_0_1_0_UpdateDataPatien.cs
├── U_0_1_1_UpdateDisplayConfigDriver.cs
├── U_0_1_2_UpdatePointOfCareConfig.cs
└── U_0_1_3_UpdateLanguageBarrier.cs
Dependencies
Downstream References
| Project | Role |
|---|---|
adas-core.Domain |
Entities, value objects, enums, DTOs, settings models, and IDefaultRepository that this layer persists. |
adas-core.Application |
All repository interfaces (I*Repository) and service contracts (IPublisherService, ISendAlertService) implemented in this project. |
adas-core.module.LightBeacons |
Module contracts for beacon-specific persistence. |
adas-core.module.Relays |
Module contracts for relay-specific persistence. |
Upstream References (projects that depend on this)
| Project | Reason |
|---|---|
adas-core (Host) |
Registers all infrastructure services and repositories in the DI container during startup. |
adas-core.Test |
Integration tests swap real repositories with in-memory substitutes or exercise the actual MongoDB-backed implementations. |
NuGet Packages
| Package | Version | Purpose |
|---|---|---|
MongoDB.Driver |
latest | MongoDB client for document persistence. |
EasyNetQ |
8.1.4 | Higher-level RabbitMQ abstractions (publisher/consumer services). |
StackExchange.Redis |
2.13.17 | Redis client for caching and distributed locking. |
MongoMigrations.Core |
4.0.15 | Document schema migration framework. |
Microsoft.Extensions.Hosting.Abstractions |
10.0.8 | IHostedService and background service registration. |
Microsoft.Extensions.Options |
10.0.8 | Options-pattern configuration binding. |
AuditLogs |
1.0.59 | Audit trail emission from repository write operations. |
MongoDB Repositories
Every repository in this project implements a corresponding interface from adas-core.Application.Repositories.Interfaces. The generic base MongoRepository<T> provides CRUD, pagination, and queryable access using the MongoDB C# Driver.
Base Repository
MongoRepository<T> implements IMongoRepository<T> and offers:
GetByIdAsync(ObjectId)— single-document lookup by_id.GetAllAsync()— unfiltered collection enumeration.InsertAsync(T)— atomic insert.UpdateAsync(ObjectId, T)— full-document replacement.DeleteAsync(ObjectId)— removal by_id.
Specialized repositories override or extend these behaviors for aggregate-specific queries (e.g., PatientRepository.GetActiveByUnitAsync, ObservationRepository.GetRangeAsync).
Repository Lifetime
Most repositories are registered as Singletons because they are stateless wrappers around a shared IMongoDatabase. The exception is PumpStateRepository, which may be Scoped when per-request pump-session tracking is required.
MongoDB Class Maps
The Utils/MongoMaps/ folder contains ~30 IEntityMapContributor implementations that register BSON mappings at application startup. This keeps the Domain layer free of MongoDB-specific attributes.
public interface IEntityMapContributor
{
void Configure();
}
| Contributor | Maps |
|---|---|
PatientMapContributor |
Patient entity — location history embedded array, ObjectId references to Person and PointOfCare. |
ObservationMapContributor |
Polymorphic observation hierarchy using BSON discriminators. |
DisplayMapContributor |
Display + DisplayConfig nested tree serialization. |
PumpMapContributor |
PumpState, PumpAlarmEvent, PumpObservation telemetry documents. |
DeviceMapContributor |
Discriminator-based polymorphic Device storage. |
AuthMapContributor |
User + Authorization embedded arrays. |
These contributors are invoked during Host startup via MongoDbHostBuilderExtension, ensuring all mappings are registered before any repository is accessed.
MongoDB Migrations
Schema evolution is handled by MongoMigrations.Core. Each migration is a C# class named with a version prefix (U_M_m_p_Description) that executes idempotent update scripts.
| Migration | Purpose |
|---|---|
U_0_1_0_UpdateDataPatien |
Corrects patient data inconsistencies post-deployment. |
U_0_1_1_UpdateDisplayConfigDriver |
Adds driver metadata to display configuration documents. |
U_0_1_2_UpdatePointOfCareConfig |
Introduces PoC-specific configuration fields. |
U_0_1_3_UpdateLanguageBarrier |
Adds language-barrier flag to patient records. |
Migrations are executed automatically at Host startup before controllers become available.
Messaging (RabbitMQ / EasyNetQ)
The project integrates RabbitMQ through EasyNetQ, which simplifies AMQP operations to a pub/sub model.
| Service | Direction | Purpose |
|---|---|---|
PublisherService |
Outbound | Dispatches domain events (alarm triggered, patient admitted, observation recorded) to configured exchanges. |
ReceiverService |
Inbound | Subscribes to topic queues and forwards messages to Application-layer handlers. |
RabbitConsumerErrorStrategy |
Error handling | Implements dead-letter queue behavior and exponential backoff for failed deliveries. |
RabbitIErrorMessageSerializer |
Serialization | Custom error-body serializer for failed-message auditing. |
Connection strings and exchange topology are configured through appsettings.json (RabbitMQSettings defined in Domain).
Redis Integration
Redis support is provided via StackExchange.Redis and registered through CacheHostBuilderExtension. The Infrastructure layer:
- Opens multiplexed connections to the Redis cluster.
- Provides connection management for the
RedisServiceandRedisLockProviderdefined inadas-core.Application. - Registers
IDistributedCachewhen available.
Redis is used primarily for:
- Distributed caching of frequently-read reference data (master lists, service configs).
- Distributed locking via
RedisLockProviderto prevent race conditions on critical operations. - Session token storage for refresh-token rotation.
Infrastructure Utilities
| Utility | Purpose |
|---|---|
MongoUtils |
Connection-string building, database factory, and collection accessor helpers. |
TypesUtils |
Reflection-based type resolution for generic repository instantiation and converter discovery. |
PatientObservationConverter |
Custom BSON serialization for PatientObservation polymorphic values. |
PersonConverter |
BSON mapping for the Person embedded document. |
CustomPointOfCareConverter |
Specialized BSON logic for PointOfCare nested structures. |
Design Rules
- Contracts Only from Upstream — Infrastructure never defines its own interfaces for cross-cutting concerns. It implements contracts from
ApplicationorDomain. - No Business Logic — Repositories execute queries and return entities. No validation, no workflow, no decision-making. That belongs in Application.
- Technology Concentration — All MongoDB, RabbitMQ, Redis, SMTP, and HTTP-specific code lives here. Inner layers remain technology-agnostic.
- Mapping Isolation — BSON class maps, EF configurations, and serialization rules are centralized in
MongoMaps/. No mapping attributes pollute Domain entities. - Connection String Injection — All external resource connection strings and API keys are injected via
IOptions<T>; never hardcoded. - Singleton by Default — Stateless repositories and services are singletons. Scoped lifetimes are reserved only for per-request state.
- Migrations Are Idempotent — Each migration script must be safe to run multiple times. Document versioning guards prevent double application.
- Error Translation — Infrastructure exceptions (Mongo socket errors, RabbitMQ disconnects, SMTP failures) are caught and re-thrown as domain exceptions or logged, never leaked raw to controllers.
- No Direct Host Coupling — Infrastructure is registered by the Host via extension methods (
AddMongoDb,AddCache), but the project does not reference the Host assembly. - Audit Trail Emission — Write operations that mutate patient data, configurations, or alarms must emit an audit event via the
AuditLogspackage before returning.
Back to adas-core Root README