63 lines
5.1 KiB
Markdown
63 lines
5.1 KiB
Markdown
|
|
---
|
|||
|
|
source_files:
|
|||
|
|
- Common/DTS.CommonCore/ModuleCatalog/AggregateModuleCatalog.cs
|
|||
|
|
generated_at: "2026-04-16T02:14:07.054648+00:00"
|
|||
|
|
model: "Qwen/Qwen3-Coder-Next-FP8"
|
|||
|
|
schema_version: 1
|
|||
|
|
sha256: "6c5b3cbd6c5102fe"
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# ModuleCatalog
|
|||
|
|
|
|||
|
|
## Documentation: `AggregateModuleCatalog`
|
|||
|
|
|
|||
|
|
### 1. Purpose
|
|||
|
|
`AggregateModuleCatalog` is a composite implementation of `IModuleCatalog` that aggregates multiple underlying module catalogs into a unified interface for module discovery and dependency resolution within the Prism-based modularity framework. It enables the system to support heterogeneous module sources (e.g., `ModuleCatalog`, `DirectoryModuleCatalog`, custom catalogs) by delegating operations to the appropriate catalog while presenting a single, flat view of all modules. It is initialized with a default `ModuleCatalog` instance, ensuring at least one catalog is always present for module registration.
|
|||
|
|
|
|||
|
|
### 2. Public Interface
|
|||
|
|
|
|||
|
|
- **`AggregateModuleCatalog()`**
|
|||
|
|
*Constructor.* Initializes a new instance with a single internal `ModuleCatalog` instance added to `_catalogs`. No parameters.
|
|||
|
|
|
|||
|
|
- **`void AddCatalog(IModuleCatalog catalog)`**
|
|||
|
|
Adds a new `IModuleCatalog` instance to the internal `_catalogs` list. Throws `ArgumentNullException` if `catalog` is `null`. No validation is performed on catalog type or compatibility (commented-out logic suggests past intent for such checks, but it is inactive).
|
|||
|
|
|
|||
|
|
- **`IEnumerable<ModuleInfo> Modules { get; }`**
|
|||
|
|
Returns a flattened enumeration of all `ModuleInfo` instances across all internal catalogs, via `SelectMany`.
|
|||
|
|
|
|||
|
|
- **`IEnumerable<ModuleInfo> GetDependentModules(ModuleInfo moduleInfo)`**
|
|||
|
|
Returns the dependencies of `moduleInfo`. Throws `InvalidOperationException` if `moduleInfo` is not contained in exactly one internal catalog (due to use of `.Single()`). Delegates to the containing catalog’s `GetDependentModules`.
|
|||
|
|
|
|||
|
|
- **`IEnumerable<ModuleInfo> CompleteListWithDependencies(IEnumerable<ModuleInfo> modules)`**
|
|||
|
|
Returns `modules` plus all transitive dependencies. Groups `modules` by the *single* catalog that contains each module (throws `InvalidOperationException` if a module is missing or duplicated across catalogs), then delegates `CompleteListWithDependencies` per catalog and flattens results.
|
|||
|
|
|
|||
|
|
- **`void Initialize()`**
|
|||
|
|
Calls `Initialize()` on each internal catalog in sequence.
|
|||
|
|
|
|||
|
|
- **`void AddModule(ModuleInfo moduleInfo)`**
|
|||
|
|
Adds `moduleInfo` exclusively to the *first* catalog in `_catalogs` (i.e., the default `ModuleCatalog` created in the constructor). Does not attempt to distribute or search for an appropriate catalog.
|
|||
|
|
|
|||
|
|
### 3. Invariants
|
|||
|
|
|
|||
|
|
- `_catalogs` always contains at least one catalog (initialized to a new `ModuleCatalog` in the constructor).
|
|||
|
|
- `AddModule` *always* targets `_catalogs[0]`; other catalogs are not modified by this method.
|
|||
|
|
- `GetDependentModules` and `CompleteListWithDependencies` assume **each `ModuleInfo` belongs to exactly one catalog**. If a `ModuleInfo` appears in multiple catalogs or none, these methods throw `InvalidOperationException` (from `.Single()`).
|
|||
|
|
- `Catalogs` is read-only (via `AsReadOnly()`), but `_catalogs` itself is mutable via `AddCatalog`.
|
|||
|
|
|
|||
|
|
### 4. Dependencies
|
|||
|
|
|
|||
|
|
- **Depends on:**
|
|||
|
|
- `Microsoft.Practices.Prism.Modularity` (specifically `IModuleCatalog`, `ModuleInfo`).
|
|||
|
|
- Standard .NET libraries: `System`, `System.Collections.Generic`, `System.Linq`.
|
|||
|
|
|
|||
|
|
- **Depended on by:**
|
|||
|
|
- Not evident from this file alone. Likely consumed by Prism’s module initialization infrastructure (e.g., `ModuleManager`, `ModuleInitializer`) or custom bootstrappers in the DTS codebase.
|
|||
|
|
|
|||
|
|
### 5. Gotchas
|
|||
|
|
|
|||
|
|
- **Critical ambiguity in `AddModule` behavior:** It silently routes *all* module additions to the first catalog, ignoring others. This may lead to modules being registered in an unintended catalog if the caller assumes uniform distribution or catalog-specific registration.
|
|||
|
|
- **Fragile catalog lookup:** Both `GetDependentModules` and `CompleteListWithDependencies` use `.Single(x => x.Modules.Contains(moduleInfo))`, which assumes uniqueness of `ModuleInfo` across catalogs. If the same `ModuleInfo` instance (by reference or identity) appears in multiple catalogs—or is missing—these methods will throw at runtime.
|
|||
|
|
- **No validation in `AddCatalog`:** Despite commented-out logic, no checks prevent adding duplicate catalog types (e.g., two `DirectoryModuleCatalog`s) or incompatible catalogs. This may cause unexpected behavior (e.g., duplicate modules, conflicting paths).
|
|||
|
|
- **No thread-safety:** The internal `_catalogs` list is modified by `AddCatalog` and `AddModule` without synchronization. Concurrent access may cause race conditions.
|
|||
|
|
- **No documentation on catalog ordering semantics:** The order of catalogs in `_catalogs` may affect behavior (e.g., `AddModule` targets index 0; `Modules` enumeration order is catalog-order-dependent), but no guarantees or documentation are provided.
|
|||
|
|
- **Commented-out code:** The commented-out logic in `AddCatalog` suggests unresolved design questions about catalog compatibility (e.g., path handling for `DirectoryModuleCatalog`), indicating potential technical debt or incomplete feature implementation.
|