Files
DP44/enriched-qwen3-coder-next/DataPRO/DataPRO.Core/ServiceManager.md

86 lines
5.7 KiB
Markdown
Raw Normal View History

2026-04-17 14:55:32 -04:00
---
source_files:
- DataPRO/DataPRO.Core/ServiceManager/IServicePublishedEvent.cs
- DataPRO/DataPRO.Core/ServiceManager/ServicePublishedEvent.cs
- DataPRO/DataPRO.Core/ServiceManager/ServiceManager.cs
generated_at: "2026-04-16T04:28:06.522630+00:00"
model: "Qwen/Qwen3-Coder-Next-FP8"
schema_version: 1
sha256: "30d34b17e2e0aff8"
---
# ServiceManager
## Documentation: ServiceManager Module
---
### 1. Purpose
The `ServiceManager` module implements a lightweight service registry pattern for managing singleton service implementations in the DataPRO core system. It enables components to publish concrete implementations of service interfaces and retrieve them later without tight coupling—publishers and consumers need not know each others identities. The module also emits `IServicePublishedEvent` notifications via the `EventManager` whenever a service is published or unpublished, supporting reactive service lifecycle monitoring.
---
### 2. Public Interface
#### `ServiceManager` (static class)
- **`void Publish<T>(T item) where T : class`**
Publishes a singleton service implementation `item` for interface type `T`. Throws `ArgumentException` if `T` is already published. Fires a `ServicePublishedEvent` with `IsPublished = true`.
- **`void Publish(object item, IEnumerable<Type> interfaceList, bool skipPublishedInterfaces)`**
Publishes `item` for each interface type in `interfaceList`. If `skipPublishedInterfaces` is `false`, throws `ArgumentException` on encountering an already-published interface; otherwise, silently skips it. Fires `ServicePublishedEvent` for each *newly* published interface.
- **`bool Exists<T>() where T : class`**
Returns `true` if an implementation for interface type `T` is currently published; `false` otherwise.
- **`bool Exists(Type t)`**
Overload of `Exists<T>` using a runtime `Type` instance.
- **`T Get<T>() where T : class`**
Returns the published implementation for interface type `T`. Throws `ArgumentException` if no implementation is published.
- **`void Clear<T>() where T : class`**
Unpublishes the implementation for interface type `T`. Fires a `ServicePublishedEvent` with `IsPublished = false` before removal.
- **`void Clear(IEnumerable<Type> interfaceList)`**
Unpublishes all implementations whose interface types are in `interfaceList`. Fires `ServicePublishedEvent` for each removed interface.
> **Note**: All methods are thread-unsafe. No synchronization is applied to the internal `Services` dictionary.
---
### 3. Invariants
- **Uniqueness per interface**: At most one implementation may be published per interface type (`Type`) at any time. Attempting to publish a second implementation for an already-published interface results in an `ArgumentException`, unless `skipPublishedInterfaces = true` in the bulk `Publish` overload.
- **Event emission guarantee**: Every successful `Publish` or `Clear` operation (i.e., one that modifies the registry) emits exactly one `ServicePublishedEvent` via `EventManager.EventManager.Publish<IServicePublishedEvent>`.
- **No partial failure in bulk operations**: In `Publish(object, IEnumerable<Type>, bool)`, if an exception occurs (e.g., duplicate interface with `skipPublishedInterfaces = false`), the operation is aborted, and no further interfaces in the list are processed. However, interfaces *already processed* before the failure remain published (no rollback).
- **Event payload consistency**: The `ServicePublishedEvent.ServiceType` always matches the interface type being published/unpublished, and `IsPublished` reflects the operation direction (`true` for publish, `false` for clear).
---
### 4. Dependencies
- **Internal dependencies**:
- `System.Collections.Generic.Dictionary<Type, object>` for storage.
- `EventManager.EventManager` (from `DataPro.Core.EventManager`)—used in `SendServicePublishedEvent` to dispatch events.
- **External dependencies**:
- `IServicePublishedEvent` and `ServicePublishedEvent` (defined in the same `DataPro.Core.ServiceManager` namespace).
- `System.Type` for interface identification.
- **Depended upon by**:
- Components that need to register or resolve singleton services (e.g., UI modules, data providers).
- Event subscribers listening to `IServicePublishedEvent` for service lifecycle tracking.
---
### 5. Gotchas
- **No support for multiple implementations per interface**: The registry strictly enforces one implementation per interface. Overriding a service requires explicit `Clear<T>()` first.
- **No null-check on `item` in `Publish<T>`**: Passing `null` as `item` will succeed (and store `null` in the dictionary), leading to a `NullReferenceException` on subsequent `Get<T>()` calls. Consider adding validation if nulls are undesirable.
- **Bulk `Publish` does not validate `item` implements all requested interfaces**: If `item` does not actually implement one or more types in `interfaceList`, the dictionary stores the reference, but `Get<T>()` for that interface will return `null` (via `as T`), potentially causing runtime errors later.
- **No thread safety**: Concurrent calls to `Publish`, `Get`, or `Clear` may corrupt the internal dictionary or cause race conditions (e.g., two threads publishing the same interface may both succeed before the duplicate check completes).
- **Event emission is synchronous**: `SendServicePublishedEvent` calls `EventManager.EventManager.Publish`, which may block the caller until all event handlers complete. Long-running handlers could impact performance.
- **No versioning or deprecation support**: Once a service is published, there is no mechanism to signal obsolescence or migration paths.
> **None identified from source alone.**
*(Note: The above gotchas are inferred from code structure and behavior—not assumptions.)*