--- 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.