Files
DP44/enriched-partialglm/DTS Viewer/DTS.Viewer.Modules/DTS.Viewer.GraphList.md

149 lines
8.6 KiB
Markdown
Raw Normal View History

2026-04-17 14:55:32 -04:00
---
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<Interface, Implementation>()` 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.