--- 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 Modules { get; }`** Returns a flattened enumeration of all `ModuleInfo` instances across all internal catalogs, via `SelectMany`. - **`IEnumerable 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 CompleteListWithDependencies(IEnumerable 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.