Files
adas-core/adas-core.Infrastructure

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

  1. Overview
  2. Responsibilities
  3. Project Structure
  4. Dependencies
  5. MongoDB Repositories
  6. MongoDB Class Maps
  7. MongoDB Migrations
  8. Messaging (RabbitMQ / EasyNetQ)
  9. Redis Integration
  10. Infrastructure Utilities
  11. 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 MongoDbHostBuilderExtension and CacheHostBuilderExtension for 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 RedisService and RedisLockProvider defined in adas-core.Application.
  • Registers IDistributedCache when available.

Redis is used primarily for:

  • Distributed caching of frequently-read reference data (master lists, service configs).
  • Distributed locking via RedisLockProvider to 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

  1. Contracts Only from Upstream — Infrastructure never defines its own interfaces for cross-cutting concerns. It implements contracts from Application or Domain.
  2. No Business Logic — Repositories execute queries and return entities. No validation, no workflow, no decision-making. That belongs in Application.
  3. Technology Concentration — All MongoDB, RabbitMQ, Redis, SMTP, and HTTP-specific code lives here. Inner layers remain technology-agnostic.
  4. Mapping Isolation — BSON class maps, EF configurations, and serialization rules are centralized in MongoMaps/. No mapping attributes pollute Domain entities.
  5. Connection String Injection — All external resource connection strings and API keys are injected via IOptions<T>; never hardcoded.
  6. Singleton by Default — Stateless repositories and services are singletons. Scoped lifetimes are reserved only for per-request state.
  7. Migrations Are Idempotent — Each migration script must be safe to run multiple times. Document versioning guards prevent double application.
  8. 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.
  9. No Direct Host Coupling — Infrastructure is registered by the Host via extension methods (AddMongoDb, AddCache), but the project does not reference the Host assembly.
  10. Audit Trail Emission — Write operations that mutate patient data, configurations, or alarms must emit an audit event via the AuditLogs package before returning.

Back to adas-core Root README