--- source_files: - DTS Viewer/DTS.Viewer.Modules/DTS.Viewer.GraphList/GraphListModule.cs - DTS Viewer/DTS.Viewer.Modules/DTS.Viewer.GraphList/ExportGraphListModule.cs generated_at: "2026-04-16T11:04:41.132033+00:00" model: "zai-org/GLM-5-FP8" schema_version: 1 sha256: "267c5c22d55f0847" --- # Documentation: GraphList and ExportGraphList Modules ## 1. Purpose This documentation covers two Prism modules within the DTS Viewer application: `GraphListModule` and `ExportGraphListModule`. Both modules follow an identical architectural pattern for registering views and view-models with the Unity dependency injection container. They provide assembly-level metadata (name, image, group, and region) via custom attributes, enabling the main application shell to discover and display these components as available modules. The `GraphListModule` provides the primary graph list visualization, while `ExportGraphListModule` appears to provide an export-oriented variant of the same functionality. --- ## 2. Public Interface ### GraphListModule Class **Namespace:** `DTS.Viewer.GraphList` | Member | Signature | Description | |--------|-----------|-------------| | Constructor | `GraphListModule(IUnityContainer unityContainer)` | Accepts an injected Unity container instance and stores it in `_unityContainer`. | | `RegisterTypes` | `void RegisterTypes(IContainerRegistry containerRegistry)` | Calls `Initialize()` to register types with the container. | | `OnInitialized` | `void OnInitialized(IContainerProvider containerProvider)` | Empty implementation (no post-initialization logic). | | `Initialize` | `void Initialize()` | Registers `IGraphMainView` → `GraphMainView` and `IGraphMainViewModel` → `GraphMainViewModel` with Unity. | ### GraphListNameAttribute Class **Namespace:** `DTS.Viewer.GraphList` **Base Class:** `TextAttribute` | Member | Signature | Description | |--------|-----------|-------------| | Constructor | `GraphListNameAttribute()` | Default constructor; initializes `_assemblyName` to `AssemblyNames.GraphList.ToString()`. | | Constructor | `GraphListNameAttribute(string s)` | Overloaded constructor; parameter `s` is unused. | | `AssemblyName` | `string AssemblyName { get; }` | Returns `_assemblyName`. | | `GetAttributeType` | `Type GetAttributeType()` | Returns `typeof(TextAttribute)`. | | `GetAssemblyName` | `string GetAssemblyName()` | Returns `AssemblyName`. | ### GraphListImageAttribute Class **Namespace:** `DTS.Viewer.GraphList` **Base Class:** `ImageAttribute` | Member | Signature | Description | |--------|-----------|-------------| | Constructor | `GraphListImageAttribute()` | Initializes `_img` via `AssemblyInfo.GetImage()`. | | Constructor | `GraphListImageAttribute(string s)` | Parameter `s` is unused; initializes `_img`. | | `AssemblyImage` | `BitmapImage AssemblyImage { get; }` | Lazy-loads image via `AssemblyInfo.GetImage(AssemblyNames.GraphList.ToString())`. | | `AssemblyName` | `string AssemblyName { get; }` | Returns `AssemblyNames.GraphList.ToString()`. | | `AssemblyGroup` | `string AssemblyGroup { get; }` | Returns `eAssemblyGroups.Viewer.ToString()`. | | `AssemblyRegion` | `eAssemblyRegion AssemblyRegion { get; }` | Returns `eAssemblyRegion.GraphListRegion`. | | `GetAttributeType` | `Type GetAttributeType()` | Returns `typeof(ImageAttribute)`. | | `GetAssemblyImage` | `BitmapImage GetAssemblyImage()` | Returns `AssemblyImage`. | | `GetAssemblyName` | `string GetAssemblyName()` | Returns `AssemblyName`. | | `GetAssemblyGroup` | `string GetAssemblyGroup()` | Returns `AssemblyGroup`. | | `GetAssemblyRegion` | `eAssemblyRegion GetAssemblyRegion()` | Returns `AssemblyRegion`. | --- ### ExportGraphListModule Class **Namespace:** `DTS.Viewer.Export` | Member | Signature | Description | |--------|-----------|-------------| | Constructor | `ExportGraphListModule(IUnityContainer unityContainer)` | Accepts an injected Unity container instance. | | `RegisterTypes` | `void RegisterTypes(IContainerRegistry containerRegistry)` | Calls `Initialize()`. | | `OnInitialized` | `void OnInitialized(IContainerProvider containerProvider)` | Empty implementation. | | `Initialize` | `void Initialize()` | Registers `IExportGraphMainView` → `ExportGraphMainView` and `IExportGraphMainViewModel` → `ExportGraphMainViewModel`. | ### ExportGraphListNameAttribute Class **Namespace:** `DTS.Viewer.Export` **Base Class:** `TextAttribute` Identical structure to `GraphListNameAttribute`, returning `AssemblyNames.GraphList.ToString()`. ### ExportGraphListImageAttribute Class **Namespace:** `DTS.Viewer.Export` **Base Class:** `ImageAttribute` Identical structure to `GraphListImageAttribute`, with the same values for `AssemblyName`, `AssemblyGroup`, and `AssemblyRegion`. --- ## 3. Invariants 1. **Constructor Injection Required:** Both modules require a non-null `IUnityContainer` instance to be injected at construction time. The container is stored but never null-checked. 2. **Single Instance per Assembly:** Both `[GraphListNameAttribute]` and `[GraphListImageAttribute]` (and their Export variants) are decorated with `AllowMultiple = false`, enforcing exactly one instance per assembly. 3. **Registration is Non-Singleton:** Both modules use `RegisterType()` without specifying a container-controlled lifetime, meaning each resolution creates a new instance (transient lifestyle). 4. **Initialize Called from RegisterTypes:** The `Initialize()` method is explicitly called within `RegisterTypes()`, not `OnInitialized()`. This ordering is intentional per Prism's module lifecycle. 5. **Fixed Assembly Metadata:** - Both modules return `AssemblyNames.GraphList.ToString()` as their assembly name. - Both return `eAssemblyGroups.Viewer.ToString()` as their group. - Both return `eAssemblyRegion.GraphListRegion` as their region. --- ## 4. Dependencies ### External Dependencies (Imports) | Namespace | Purpose | |-----------|---------| | `System` | Core .NET types (`Type`, `AttributeUsage`, `AttributeTargets`). | | `System.Windows.Media.Imaging` | `BitmapImage` for assembly imagery. | | `Prism.Ioc` | `IContainerProvider`, `IContainerRegistry` for Prism DI abstraction. | | `Prism.Modularity` | `IModule`, `ModuleAttribute` for modular composition. | | `Unity` | `IUnityContainer` for Unity-specific DI operations. | ### Internal Dependencies (Inferred) | Namespace | Usage | |-----------|-------| | `DTS.Common` | `AssemblyNames` enum, `eAssemblyGroups` enum, `eAssemblyRegion` enum, `AssemblyInfo` static class. | | `DTS.Common.Interface` | `TextAttribute`, `ImageAttribute` base classes. | | `DTS.Viewer.GraphList` (local) | `GraphMainView`, `GraphMainViewModel`, `IGraphMainView`, `IGraphMainViewModel`. | | `DTS.Viewer.Export` (local) | `ExportGraphMainView`, `ExportGraphMainViewModel`, `IExportGraphMainView`, `IExportGraphMainViewModel`. | ### Consumers Unknown from source alone. The modules are discovered and loaded by a Prism-based shell application that scans for `IModule` implementations and assembly attributes. --- ## 5. Gotchas 1. **Duplicate Assembly Name Values:** Both `GraphListNameAttribute` and `ExportGraphListNameAttribute` return `AssemblyNames.GraphList.ToString()`. This may cause ambiguity if the shell application uses assembly name as a unique identifier. It is unclear whether this is intentional (shared identity) or a copy-paste oversight. 2. **Duplicate Region Assignment:** Both modules declare `eAssemblyRegion.GraphListRegion`. If the shell uses region-based navigation, both views may attempt to load into the same region, potentially causing conflicts or overwrites. 3. **Redundant Image Initialization:** In `GraphListImageAttribute` and `ExportGraphListImageAttribute`, the `_img` field is assigned in both the constructor and the `AssemblyImage` getter. The getter reassigns `_img` on every access, defeating the purpose of the constructor initialization. 4. **Unused Constructor Parameter:** Both attribute classes accept a `string s` parameter in an overloaded constructor but never use it. The ReSharper suppression comment `// ReSharper disable UnusedParameter.Local` acknowledges this but does not explain the design rationale. 5. **Empty OnInitialized:** Both modules leave `OnInitialized()` empty. If module initialization logic is expected here, it will not execute. The actual registration happens in `RegisterTypes()` → `Initialize()`. 6. **No Lifetime Management:** The `RegisterType` calls do not specify `ContainerControlledLifetimeManager`, meaning views and view-models are transient. If singleton behavior is expected (as suggested by the comment "Register View & View-Model with Unity dependency injection container as a singleton"), the implementation does not match the intent.