Files
DP44/enriched-qwen3-coder-next/DataPRO/DataPRO.Core/ServiceManager.md
2026-04-17 14:55:32 -04:00

5.7 KiB
Raw Blame History

source_files, generated_at, model, schema_version, sha256
source_files generated_at model schema_version sha256
DataPRO/DataPRO.Core/ServiceManager/IServicePublishedEvent.cs
DataPRO/DataPRO.Core/ServiceManager/ServicePublishedEvent.cs
DataPRO/DataPRO.Core/ServiceManager/ServiceManager.cs
2026-04-16T04:28:06.522630+00:00 Qwen/Qwen3-Coder-Next-FP8 1 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.)