adas-core.Application — Use Case Layer
The Application Layer of the ADAS Core platform.
Contains application services, use case orchestration, repository contracts, caching abstractions, and domain-specific exceptions. This layer defines what the system does, delegating how to the Infrastructure layer.
Table of Contents
- Overview
- Responsibilities
- Project Structure
- Dependencies
- Repository Contracts
- Application Services
- Caching Abstractions
- Exceptions
- Environment Customizations
- Design Rules
Overview
adas-core.Application sits between the Domain and Infrastructure layers. It orchestrates domain entities into complete use cases, enforces application-level rules, and exposes repository contracts that Infrastructure implements.
Key characteristics:
- Pure orchestration — Services coordinate domain objects but contain no persistence logic.
- Repository contracts — Interfaces in
Repositories/Interfaces/define data access contracts; concrete implementations live inadas-core.Infrastructure. - DTO-less where possible — Services consume and return domain entities directly when serialization concerns are handled upstream.
- Pluggable caching — Abstracted behind
ICacheServicewith Redis or in-memory fallbacks. - Environment-specific logic — Calculated observations vary per deployment via the
Customizationsfolder.
Responsibilities
| Concern | What this project does |
|---|---|
| Use Case Orchestration | Application services execute high-level workflows (admit patient, record observation, trigger alert, etc.). |
| Repository Contracts | Defines I* repository interfaces that Infrastructure must satisfy. |
| Caching Strategy | Provides ICacheService, ILockProvider, and LockManagerService for distributed or in-memory caching. |
| External Provider Facade | AdasProvider / BaseProvider abstract external integrations so domain logic remains clean. |
| Real-Time Subscriptions | SubscribersService and grouped subscriber models manage WebSocket client subscriptions. |
| Calculated Observations | CalculatedObservationsService evaluates patient observations using rules customized per environment. |
| Scheduled Jobs | SchedulerService coordinates Quartz-based background tasks. |
| Exception Taxonomy | Domain-relevant exceptions (NotFoundException, ConflictException, etc.) for predictable error handling. |
Project Structure
adas-core.Application/
├── Repositories/
│ └── Interfaces/ # Repository contracts (~40 interfaces)
│ ├── IMongoRepository.cs
│ ├── IUserRepository.cs
│ ├── IPatientRepository.cs
│ ├── IAdmissionRepository.cs
│ ├── IObservationRepository.cs
│ ├── ITreatmentRepository.cs
│ ├── IAlarmRepository.cs
│ ├── IDeviceRepository.cs
│ ├── ILightBeaconRepository.cs
│ ├── IRelayRepository.cs
│ ├── IPump*Repository.cs
│ ├── IRecordingAlertRepository.cs
│ ├── IConfig*Repository.cs
│ ├── IUnitRepository.cs
│ ├── IDisplay*Repository.cs
│ ├── IAppointmentRepository.cs
│ ├── IPatientCarePlanRepository.cs
│ ├── IMasterListRepository.cs
│ └── ...
├── Services/
│ ├── Interfaces/ # Service contracts (~40 interfaces)
│ │ ├── IAuthService.cs
│ │ ├── IPatientService.cs
│ │ ├── IObservationService.cs
│ │ ├── ICalculatedObservationsService.cs
│ │ ├── ITreatmentService.cs
│ │ ├── IDeviceService.cs
│ │ ├── IAlarmService.cs
│ │ ├── IDisplayService.cs
│ │ ├── IConfigObservationService.cs
│ │ ├── IUnitService.cs
│ │ ├── IAppointmentService.cs
│ │ ├── IPublisherService.cs
│ │ ├── ICacheService.cs
│ │ ├── ILockProvider.cs
│ │ └── ...
│ ├── AuthService.cs
│ ├── PatientService.cs
│ ├── AdmissionService.cs
│ ├── ObservationService.cs
│ ├── CalculatedObservationsService.cs
│ ├── DefaultCalculatedObservations.cs
│ ├── TreatmentService.cs
│ ├── AlarmService.cs
│ ├── DeviceService.cs
│ ├── CameraService.cs
│ ├── Config*Service.cs
│ ├── DisplayService.cs
│ ├── PointOfCareService.cs
│ ├── AppointmentService.cs
│ ├── PatientCarePlanService.cs
│ ├── Archive*Service.cs
│ ├── Recording*Service.cs
│ ├── MasterListService.cs
│ ├── MasterListServiceFactory.cs
│ ├── PermissionService.cs
│ ├── AdminPanelService.cs
│ ├── FileService.cs
│ ├── LocalAuditService.cs
│ ├── SubscribersService.cs
│ ├── SchedulerService.cs
│ └── Caching/
│ ├── CacheService.cs
│ ├── NoCacheService.cs
│ ├── RedisService.cs
│ ├── CacheDispatcher.cs
│ ├── LockManagerService.cs
│ ├── InMemoryLockProvider.cs
│ └── RedisLockProvider.cs
├── Exceptions/
│ ├── APIRequestException.cs
│ ├── BadRequestException.cs
│ ├── ConflictException.cs
│ ├── NotFoundException.cs
│ ├── UnauthorizedException.cs
│ ├── TokenException.cs
│ ├── UnprocessableEntityException.cs
│ └── ...
├── Customizations/ # Environment-specific calculated-observation rules
│ ├── BD/
│ ├── CHUO/
│ ├── H12O/UCIN/
│ ├── HGM/
│ ├── HPAZ/
│ ├── HRYC/
│ ├── HUVH/UCIN/
│ ├── HUVH/UCIA/
│ └── NursePlan/
│ └── CalculatedObservations.cs
├── Providers/
│ ├── BaseProvider.cs
│ └── AdasProvider.cs
└── Subscriptions/
├── SubscribersService.cs
├── WsSuscriber.cs
└── WsSubscriberGrouped.cs
Dependencies
Downstream References
| Project | Role |
|---|---|
adas-core.Domain |
Domain entities, value objects, and business rules consumed by application services. |
Upstream References (projects that depend on this)
| Project | Reason |
|---|---|
adas-core (Host) |
Registers application services and invokes them from controllers. |
adas-core.Infrastructure |
Implements all repository contracts defined in Repositories/Interfaces/. |
adas-core.Authentication |
Uses IAuthService and user-related service contracts. |
adas-core.module.LightBeacons |
Consumes shared application service interfaces. |
adas-core.module.ProxyDevices |
Consumes shared application service interfaces. |
adas-core.module.Relays |
Consumes shared application service interfaces. |
adas-core.Test |
Mocks application service interfaces in unit tests. |
NuGet Packages
| Package | Version | Purpose |
|---|---|---|
AutoMapper |
16.1.1 | Entity ↔ projection mapping. |
MongoDB.Driver |
3.9.0 | Repository interface type signatures. |
Quartz |
3.18.1 | Scheduling primitives for background jobs. |
StackExchange.Redis |
2.13.17 | Redis caching abstractions. |
Microsoft.Extensions.Caching.Memory |
10.0.8 | In-memory caching fallback. |
Microsoft.Extensions.Http |
10.0.8 | Typed HTTP clients for provider integrations. |
Microsoft.IdentityModel.JsonWebTokens |
8.18.0 | JWT validation helpers for auth services. |
Microsoft.CodeAnalysis.CSharp.Scripting |
5.3.0 | Dynamic expression evaluation for calculated observations. |
AuditLogs |
1.0.59 | Audit trail tagging in use cases. |
Repository Contracts
All repository interfaces reside in Repositories/Interfaces/. They are contracts only — no implementation. This enforces the Dependency Inversion Principle: Application defines the interface, Infrastructure provides the concrete MongoDB-backed classes.
Generic Base Contract
public interface IMongoRepository<T> where T : class
{
Task<T?> GetByIdAsync(ObjectId id);
Task<IEnumerable<T>> GetAllAsync();
Task<T> InsertAsync(T entity);
Task UpdateAsync(ObjectId id, T entity);
Task DeleteAsync(ObjectId id);
}
Specialized Contracts
Derived interfaces extend IMongoRepository<T> or stand alone for aggregate-specific queries:
IPatientRepository— CRUD + admission/discharge history lookups.IObservationRepository— Inserts with archive triggers, range queries.IPumpStateRepository— Scoped lifetime; tracks real-time pump telemetry.IAlarmRepository— Acknowledge, escalate, and history retrieval.IDisplayConfigRepository— Display layout and card/chart configuration.
Rule: Every repository method name must describe intent, not mechanism (e.g.,
GetActiveByUnitAsyncrather thanFindByQuery).
Application Services
Services in Services/ encapsulate complete use cases. They are registered as Singletons in the DI container unless they hold per-request state.
Service Categories
| Category | Examples |
|---|---|
| Patient Management | PatientService, AdmissionService, DischargeService, PatientCarePlanService |
| Observations | ObservationService, ObservationDemoService, CalculatedObservationsService, GroupedObservationService |
| Clinical | TreatmentService, MedicineService, DiagnosisService |
| Devices | DeviceService, CameraService, PumpService |
| Alerts | AlarmService, AlertValuesService |
| Configuration | ConfigObservationService, ConfigPumpsService, ConfigUnitsService, ServiceConfigService |
| Displays | DisplayService, DisplayConfigService |
| System | AuthService, PermissionService, UnitService, MasterListService, AdminPanelService |
| Archival | ArchivePatientObservationsService, ArchivedPatientService, HistoricalConfigChangesService |
| Communication | SubscribersService, PublisherService, ClientMessageService |
Calculated Observations
CalculatedObservationsService evaluates derived metrics (e.g., early warning scores, trend indicators) using ICalculatedObservations strategy pattern. Per-environment overrides are loaded from the Customizations/ folder based on ASPNETCORE_ENVIRONMENT.
Example environment mappings:
| Environment | Customization Path |
|---|---|
H12O |
Customizations/H12O/UCIN/CalculatedObservations.cs |
HRYCM |
Customizations/HRYC/CalculatedObservations.cs |
HPAZ |
Customizations/HPAZ/CalculatedObservations.cs |
HUVH-UCIN |
Customizations/HUVH/UCIN/CalculatedObservations.cs |
HUVH-UCIA |
Customizations/HUVH/UCIA/CalculatedObservations.cs |
CHUO |
Customizations/CHUO/CalculatedObservations.cs |
NursePlan |
Customizations/NursePlan/CalculatedObservations.cs |
Caching Abstractions
The caching stack abstracts Redis and in-memory behind common interfaces so services remain cache-agnostic.
| Component | Responsibility |
|---|---|
ICacheService |
Contract for get, set, remove, and sliding/absolute expiration. |
CacheService |
Composite dispatcher that routes to Redis or memory. |
RedisService |
Concrete Redis implementation using StackExchange.Redis. |
NoCacheService |
Null-object pattern for disabling cache in test environments. |
ILockProvider |
Distributed or in-memory lock acquisition. |
LockManagerService |
Orchestrates lock lifecycle (acquire, extend, release). |
RedisLockProvider |
Redis-backed distributed locking. |
InMemoryLockProvider |
Lightweight semaphore-based locking for single-instance deployments. |
Exceptions
The Exceptions/ folder defines a predictable error taxonomy used by controllers to map to HTTP status codes.
| Exception | Mapped HTTP Status | Usage |
|---|---|---|
BadRequestException |
400 Bad Request |
Malformed input, validation failure. |
UnauthorizedException |
401 Unauthorized |
Missing or invalid credentials. |
ForbbidenException |
403 Forbidden |
Authenticated but insufficient permissions. |
NotFoundException |
404 Not Found |
Resource does not exist. |
ConflictException |
409 Conflict |
Concurrent modification or duplicate key. |
UnprocessableEntityException |
422 Unprocessable Entity |
Semantic validation failure. |
InvalidFormatException |
400 Bad Request |
Payload format mismatch. |
CustomArgumentException |
400 Bad Request |
Invalid argument supplied. |
APIRequestException |
502 Bad Gateway |
External provider call failure. |
TokenException |
401 Unauthorized |
JWT parsing or validation error. |
Environment Customizations
Customizations/ contains per-client overrides for CalculatedObservations. These are compiled into the assembly conditionally or selected at runtime based on environment.
This avoids branching domain logic and keeps environment-specific rules isolated:
Customizations/
├── BD/
├── CHUO/
├── H12O/UCIN/
├── HGM/
├── HPAZ/
├── HRYC/
├── HUVH/UCIN/
├── HUVH/UCIA/
└── NursePlan/
Rule: Customizations may only override
ICalculatedObservations; they must not introduce new repository calls or bypass service contracts.
Design Rules
- No Persistence Logic — Application services never call MongoDB, Redis, or HTTP clients directly. They use injected repository interfaces and provider abstractions.
- Dependency Direction — This project references only
adas-core.Domain. No references to Infrastructure, Authentication, or Modules. - Contracts First — All repositories and external providers must expose an interface in this project before Infrastructure implements them.
- Single Responsibility Per Service — One service per bounded-context use case; avoid god services.
- Environment Agnosticism — Core services must compile and run without environment-specific customizations. Overrides are opt-in.
- Exception-Driven Flow Control — Use typed exceptions for expected error paths; never throw raw
ExceptionorApplicationException. - Thread Safety — Singleton services must be stateless or use immutable state. Per-request state lives in scoped repositories.
- Cache Invalidation Ownership — The service that writes data is responsible for invalidating related cache keys.
- Lazy Evaluation — Heavy graph traversals use deferred execution until the repository materializes results.
- Audit Trail Awareness — Sensitive mutations (patient admission, alarm acknowledge, config changes) must tag audit metadata before returning.
Back to adas-core Root README