Files

158 lines
12 KiB
Markdown
Raw Permalink Normal View History

2026-04-17 14:55:32 -04:00
---
source_files:
- DTS Viewer/DTS.Viewer.Reports/DTS.Viewer.PSDReport/PSDReportModule.cs
- DTS Viewer/DTS.Viewer.Reports/DTS.Viewer.PSDReport/PSDReportSession.cs
- DTS Viewer/DTS.Viewer.Reports/DTS.Viewer.PSDReport/Bootstrapper.cs
generated_at: "2026-04-16T13:38:15.717558+00:00"
model: "zai-org/GLM-5-FP8"
schema_version: 1
sha256: "24a83d36ea7d74c2"
---
# PSDReport Module Documentation
## 1. Purpose
The `DTS.Viewer.PSDReport` module is a Prism-based modular component within the DTS Viewer application responsible for providing PSD (Power Spectral Density) report visualization functionality. It implements the `IModule` interface from the Prism framework, enabling dynamic loading and lifecycle management. The module manages its own bootstrapping process, plugin loading, and region-based view composition, supporting both standalone operation and integration within a larger host application.
---
## 2. Public Interface
### PSDReportModule Class
**Implements:** `IPSDReportModule`, `IModule`
| Member | Signature | Description |
|--------|-----------|-------------|
| `SessionStarted` | `public bool SessionStarted { get; private set; }` | Property indicating whether a session has been started. Set to `true` after `StartSession()` completes. |
| Constructor | `public PSDReportModule(IUnityContainer unityContainer)` | Constructs the module with an injected Unity container. |
| `Initialize` | `public void Initialize()` | Registers `IPSDReportModule` to `PSDReportModule` with container-controlled lifetime. |
| `StartSession` | `public void StartSession()` | Publishes a `LoadViewModulEvent` with `LoadViewModulArg` and sets `SessionStarted` to `true`. |
| `RegisterTypes` | `public void RegisterTypes(IContainerRegistry containerRegistry)` | Prism module lifecycle method; delegates to `Initialize()`. |
| `OnInitialized` | `public void OnInitialized(IContainerProvider containerProvider)` | Prism module lifecycle method; currently empty implementation. |
### PSDReportSession Class
| Member | Signature | Description |
|--------|-----------|-------------|
| `Container` | `public IUnityContainer Container { get; private set; }` | Exposes the Unity container after session creation. |
| `_serviceLocator` | `public IServiceLocator _serviceLocator { get; private set; }` | Exposes the service locator after session creation. |
| `_eventAggregator` | `public IEventAggregator _eventAggregator { get; private set; }` | Exposes the event aggregator after session creation. |
| `_regionManager` | `public IRegionManager _regionManager { get; private set; }` | Exposes the region manager after session creation. |
| `CustomConfigPath` | `public string CustomConfigPath { get; set; }` | Path to custom configuration file; defaults to empty string. |
| Constructor | `public PSDReportSession()` | Empty constructor. |
| `CreateSession` | `public void CreateSession(bool standalone, string customConfigPath = "")` | Main entry point; creates bootstrapper, resolves core services, loads plugins via `PluginManager`, and publishes `AssemblyListNotificationViewer` event. |
| `Terminate` | `public void Terminate()` | Called during application shutdown; currently empty. |
### Bootstrapper Class
**Inherits:** `UnityBootstrapper`
| Member | Signature | Description |
|--------|-----------|-------------|
| `_ServiceLocator` | `public IServiceLocator _ServiceLocator { get; private set; }` | Resolved service locator instance. |
| `_EventAggregator` | `public IEventAggregator _EventAggregator { get; private set; }` | Resolved event aggregator instance. |
| `Standalone` | `public bool Standalone { get; set; }` | Indicates whether running in standalone mode. |
| `CustomConfigPath` | `public string CustomConfigPath { get; set; }` | Path to custom configuration. |
| Constructor | `public Bootstrapper(bool standalone, string customConfigPath = "")` | Initializes bootstrapper with mode and config path. |
| `ConfigureContainer` | `protected override void ConfigureContainer()` | Registers `IPSDReportMainViewGrid``PSDReportMainViewGrid` and `IPSDReportMainViewModel``PSDReportMainViewModel` (singleton). |
| `ConfigureRegionAdapterMappings` | `protected override RegionAdapterMappings ConfigureRegionAdapterMappings()` | Registers region adapters for `Selector`, `ItemsControl`, `ContentControl`, and conditionally `StackPanel` (standalone mode only). |
| `CreateShell` | `protected override DependencyObject CreateShell()` | Creates the main shell view, registers regions, initializes the view model, and returns the view. |
| `CreateModuleCatalog` | `protected override IModuleCatalog CreateModuleCatalog()` | Returns resolved `IModuleCatalog` or new `AggregateModuleCatalog`. |
| `ConfigureModuleCatalog` | `protected override void ConfigureModuleCatalog()` | In standalone mode, reads plugin folders from config section `DTS.Common.Core.PluginLib.Config` and adds `DirectoryModuleCatalog`. |
| `InitializeModules` | `protected override void InitializeModules()` | In standalone mode, registers `IDTSViewRegionManager``DTSViewRegionManager` (singleton) and calls base. |
### PSDReportModuleNameAttribute Class
**Inherits:** `TextAttribute`
| Member | Signature | Description |
|--------|-----------|-------------|
| Constructor | `public PSDReportModuleNameAttribute()` / `public PSDReportModuleNameAttribute(string s)` | Sets `AssemblyName` to `AssemblyNames.PSDReport.ToString()`. |
| `AssemblyName` | `public override string AssemblyName { get; }` | Returns the PSDReport assembly name. |
| `GetAttributeType` | `public override Type GetAttributeType()` | Returns `typeof(TextAttribute)`. |
| `GetAssemblyName` | `public override string GetAssemblyName()` | Returns `AssemblyName`. |
### PSDReportModuleImageAttribute Class
**Inherits:** `ImageAttribute`
| Member | Signature | Description |
|--------|-----------|-------------|
| `AssemblyImage` | `public override BitmapImage AssemblyImage { get; }` | Loads image via `AssemblyInfo.GetImage(AssemblyNames.PSDReport.ToString())`. |
| `AssemblyName` | `public override string AssemblyName { get; }` | Returns `AssemblyNames.PSDReport.ToString()`. |
| `AssemblyGroup` | `public override string AssemblyGroup { get; }` | Returns `eAssemblyGroups.Viewer.ToString()`. |
| `AssemblyRegion` | `public override eAssemblyRegion AssemblyRegion { get; }` | Returns `eAssemblyRegion.PSDReportRegion`. |
| `GetAssemblyImage` | `public override BitmapImage GetAssemblyImage()` | Returns `AssemblyImage`. |
| `GetAssemblyName` | `public override string GetAssemblyName()` | Returns `AssemblyName`. |
| `GetAssemblyGroup` | `public override string GetAssemblyGroup()` | Returns `AssemblyGroup`. |
| `GetAssemblyRegion` | `public override eAssemblyRegion GetAssemblyRegion()` | Returns `AssemblyRegion`. |
---
## 3. Invariants
1. **Single Bootstrapper Instance:** The `_bootstrapper` field in `PSDReportSession` must only be created once. Re-creating it will not re-initialize modules already loaded in the `DirectoryModuleCatalog`.
2. **Container Registration Order:** `Initialize()` must be called (via `RegisterTypes()`) before `StartSession()` to ensure `IPSDReportModule` is registered in the container.
3. **Standalone Mode Behavior:** Several behaviors are conditional on `Standalone` being `true`:
- `StackPanelRegionAdapter` registration
- Module catalog configuration from config file
- `IDTSViewRegionManager` registration
- Shell parent context assignment
4. **Region Registration:** Regions are only added if they do not already exist (`ContainsRegionWithName` check in `CreateShell`).
5. **Assembly Attributes:** Both `PSDReportModuleNameAttribute` and `PSDReportModuleImageAttribute` are applied at assembly level with `AllowMultiple = false`.
---
## 4. Dependencies
### External Dependencies (Imports)
| Namespace | Purpose |
|-----------|---------|
| `Prism.Ioc`, `Prism.Modularity`, `Prism.Events` | Modern Prism framework (modularity, DI, events) |
| `Microsoft.Practices.Prism.Events`, `Microsoft.Practices.Prism.Modularity`, `Microsoft.Practices.Prism.Regions`, `Microsoft.Practices.Prism.UnityExtensions` | Legacy Prism framework (used by `Bootstrapper` and `PSDReportSession`) |
| `Unity`, `Microsoft.Practices.Unity` | Unity IoC container |
| `Microsoft.Practices.ServiceLocation` | Service locator pattern |
| `DTS.Common` | Common utilities (`AssemblyNames`, `AssemblyInfo`) |
| `DTS.Common.Events` | Event definitions (`LoadViewModulEvent`, `LoadViewModulArg`, `AssemblyListNotificationViewer`, `AssemblyListInfo`) |
| `DTS.Common.Interface` | Interfaces (`IPSDReportModule`, `IPSDReportMainViewGrid`, `IPSDReportMainViewModel`, `IShellViewModel`, `IDTSViewRegionManager`) |
| `DTS.Common.Base` | Base types |
| `DTS.Common.Core.PluginLib` | Plugin infrastructure (`PluginManager`, `PluginConfigSectionHandler`, `FilterHashElement`) |
| `System.Windows`, `System.Windows.Controls` | WPF UI framework |
| `System.Configuration` | Configuration management |
| `System.ComponentModel.Composition.Hosting` | MEF composition (for `DirectoryModuleCatalog` in legacy Prism) |
### Internal Dependencies (Inferred)
The following types are referenced but not defined in the provided source:
- `IPSDReportModule` (interface)
- `IPSDReportMainViewGrid`, `PSDReportMainViewGrid`
- `IPSDReportMainViewModel`, `PSDReportMainViewModel`
- `IShellViewModel`
- `IDTSViewRegionManager`, `DTSViewRegionManager`
- `TextAttribute`, `ImageAttribute` (base classes)
- `AssemblyNames`, `AssemblyInfo`, `eAssemblyGroups`, `eAssemblyRegion` (enums/utilities)
- `LoadViewModulEvent`, `LoadViewModulArg`, `AssemblyListNotificationViewer`, `AssemblyListInfo` (events)
- `PluginManager`, `PluginConfigSectionHandler`, `FilterHashElement`
---
## 5. Gotchas
1. **Mixed Prism Versions:** The codebase uses both modern Prism namespaces (`Prism.*`) and legacy Prism namespaces (`Microsoft.Practices.Prism.*`). `PSDReportModule` uses modern Prism interfaces (`Prism.Modularity.IModule`), while `Bootstrapper` and `PSDReportSession` use legacy Prism (`UnityBootstrapper`, `Microsoft.Practices.Prism.*`). This suggests an incomplete migration.
2. **Bootstrapper Memory Footprint:** The comment in `PSDReportSession` explicitly warns: *"Do not try to re-create the bootstrapper. Once modules are loaded, they will be be loaded into the DirectoryModuleCatalog and each Module initialization will not be called."* The bootstrapper loads ~40 MB into memory and cannot be fully unloaded without additional effort.
3. **Silent Failures in Region Adapter Registration:** `ConfigureRegionAdapterMappings()` uses empty `try { } catch { }` blocks to suppress exceptions when registering region adapters, potentially hiding configuration issues.
4. **Unconventional Initialization Pattern:** `PSDReportModule.RegisterTypes()` calls `Initialize()`, which registers the module's own type. This is unusual—typically `RegisterTypes` registers dependencies, not the module itself.
5. **Unclear Purpose:** The `PSDReportSession` class has a comment *"I think we need it..."* indicating uncertainty about its necessity.
6. **Exception Swallowing in CreateShell:** The `CreateShell()` method catches all exceptions, stores only the message in a local variable `s`, and returns `null`. This suppresses error details and could make debugging difficult.
7. **Commented-Out Code:** `ConfigureContainer()` contains commented-out registration code for `IPSDReportMainView`, suggesting refactoring in progress or dead code.
8. **Standalone Mode Required for Plugin Loading:** `ConfigureModuleCatalog()` and `InitializeModules()` both early-return if `Standalone` is `false`, meaning plugin discovery from directories only occurs in standalone mode.