242 lines
10 KiB
Markdown
242 lines
10 KiB
Markdown
---
|
|
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-16T10:59:56.665208+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 plugin module for the DTS Viewer application that provides PSD (Power Spectral Density) report functionality. It implements the `IModule` interface for modular composition and can operate in both standalone and integrated modes. The module includes custom assembly attributes for metadata discovery, a session management system for bootstrapping Prism infrastructure, and a custom `UnityBootstrapper` for configuring dependency injection, region adapters, and dynamic module loading.
|
|
|
|
---
|
|
|
|
## 2. Public Interface
|
|
|
|
### PSDReportModule.cs
|
|
|
|
**Class: `PSDReportModule`**
|
|
```csharp
|
|
public PSDReportModule(IUnityContainer unityContainer)
|
|
```
|
|
Constructor accepting an `IUnityContainer` dependency injection.
|
|
|
|
```csharp
|
|
public void Initialize()
|
|
```
|
|
Registers `IPSDReportModule` to `PSDReportModule` with `ContainerControlledLifetimeManager` (singleton lifetime).
|
|
|
|
```csharp
|
|
public void StartSession()
|
|
```
|
|
Resolves `IEventAggregator`, publishes a `LoadViewModulEvent` with `LoadViewModulArg`, and sets `SessionStarted` to `true`.
|
|
|
|
```csharp
|
|
public void RegisterTypes(IContainerRegistry containerRegistry)
|
|
```
|
|
Prism module lifecycle method; calls `Initialize()`.
|
|
|
|
```csharp
|
|
public void OnInitialized(IContainerProvider containerProvider)
|
|
```
|
|
Prism module lifecycle method; currently empty implementation.
|
|
|
|
**Property: `SessionStarted`** (read-only)
|
|
```csharp
|
|
public bool SessionStarted { get; private set; }
|
|
```
|
|
Indicates whether `StartSession()` has been called.
|
|
|
|
---
|
|
|
|
**Class: `PSDReportModuleNameAttribute`** (extends `TextAttribute`)
|
|
```csharp
|
|
public PSDReportModuleNameAttribute()
|
|
public PSDReportModuleNameAttribute(string s)
|
|
```
|
|
Assembly-level attribute returning `AssemblyNames.PSDReport.ToString()` for `AssemblyName`.
|
|
|
|
```csharp
|
|
public override Type GetAttributeType()
|
|
public override string GetAssemblyName()
|
|
```
|
|
|
|
---
|
|
|
|
**Class: `PSDReportModuleImageAttribute`** (extends `ImageAttribute`)
|
|
```csharp
|
|
public PSDReportModuleImageAttribute()
|
|
public PSDReportModuleImageAttribute(string s)
|
|
```
|
|
Assembly-level attribute providing image, name, group, and region metadata.
|
|
|
|
```csharp
|
|
public override BitmapImage AssemblyImage { get; }
|
|
public override string AssemblyName { get; }
|
|
public override string AssemblyGroup { get; } // Returns eAssemblyGroups.Viewer.ToString()
|
|
public override eAssemblyRegion AssemblyRegion { get; } // Returns eAssemblyRegion.PSDReportRegion
|
|
```
|
|
|
|
---
|
|
|
|
### PSDReportSession.cs
|
|
|
|
**Class: `PSDReportSession`**
|
|
```csharp
|
|
public PSDReportSession()
|
|
```
|
|
Default (empty) constructor.
|
|
|
|
```csharp
|
|
public void CreateSession(bool standalone, string customConfigPath = "")
|
|
```
|
|
Creates the bootstrapper, resolves container services (`IUnityContainer`, `IEventAggregator`, `IServiceLocator`, `IRegionManager`), loads plugins via `PluginManager`, and publishes the plugin list via `AssemblyListNotificationViewer` event.
|
|
|
|
```csharp
|
|
public void Terminate()
|
|
```
|
|
Empty implementation; intended for shutdown scenarios.
|
|
|
|
**Properties:**
|
|
```csharp
|
|
public IUnityContainer Container { get; private set; }
|
|
public IServiceLocator _serviceLocator { get; private set; }
|
|
public IEventAggregator _eventAggregator { get; private set; }
|
|
public IRegionManager _regionManager { get; private set; }
|
|
public string CustomConfigPath { get; set; }
|
|
```
|
|
|
|
---
|
|
|
|
### Bootstrapper.cs
|
|
|
|
**Class: `Bootstrapper`** (extends `UnityBootstrapper`)
|
|
```csharp
|
|
public Bootstrapper(bool standalone, string customConfigPath = "")
|
|
```
|
|
Constructor accepting standalone mode flag and optional custom config path.
|
|
|
|
```csharp
|
|
protected override void ConfigureContainer()
|
|
```
|
|
Registers `IPSDReportMainViewGrid` to `PSDReportMainViewGrid` and `IPSDReportMainViewModel` to `PSDReportMainViewModel` (singleton). Calls `base.ConfigureContainer()`.
|
|
|
|
```csharp
|
|
protected override RegionAdapterMappings ConfigureRegionAdapterMappings()
|
|
```
|
|
Registers region adapters for `Selector`, `ItemsControl`, `ContentControl`, and conditionally `StackPanel` (standalone mode only). Each registration is wrapped in try/catch to handle duplicate mappings.
|
|
|
|
```csharp
|
|
protected override DependencyObject CreateShell()
|
|
```
|
|
Creates the shell by resolving `IPSDReportMainViewModel`, registering regions dynamically, setting DataContext, and initializing the view model. Returns `null` on exception.
|
|
|
|
```csharp
|
|
protected override IModuleCatalog CreateModuleCatalog()
|
|
```
|
|
Returns resolved `IModuleCatalog` or creates new `AggregateModuleCatalog`.
|
|
|
|
```csharp
|
|
protected override void ConfigureModuleCatalog()
|
|
```
|
|
For standalone mode only: reads plugin folder paths from configuration section `DTS.Common.Core.PluginLib.Config` and creates a `DirectoryModuleCatalog`.
|
|
|
|
```csharp
|
|
protected override void InitializeModules()
|
|
```
|
|
For standalone mode only: registers `IDTSViewRegionManager` to `DTSViewRegionManager` (singleton) and calls `base.InitializeModules()`.
|
|
|
|
**Properties:**
|
|
```csharp
|
|
public bool Standalone { get; set; }
|
|
public string CustomConfigPath { get; set; }
|
|
public IServiceLocator _ServiceLocator { get; private set; }
|
|
public IEventAggregator _EventAggregator { get; private set; }
|
|
```
|
|
|
|
---
|
|
|
|
## 3. Invariants
|
|
|
|
1. **Singleton Registration**: `IPSDReportModule` is registered with `ContainerControlledLifetimeManager`, ensuring a single instance per container.
|
|
|
|
2. **Session State**: `SessionStarted` is `false` until `StartSession()` is called; it cannot be reset to `false` through the public interface.
|
|
|
|
3. **Bootstrapper Creation**: `CreateBootstrapper()` will not create a new bootstrapper if `_bootstrapper` is already non-null.
|
|
|
|
4. **Standalone Mode Behavior**:
|
|
- `ConfigureModuleCatalog()` only adds directory catalog when `Standalone` is `true`.
|
|
- `InitializeModules()` only registers `IDTSViewRegionManager` when `Standalone` is `true`.
|
|
- `StackPanel` region adapter is only registered when `Standalone` is `true`.
|
|
|
|
5. **Region Registration**: In `CreateShell()`, regions are only added if they don't already exist (`ContainsRegionWithName` check).
|
|
|
|
6. **Assembly Attributes**: Both `PSDReportModuleNameAttribute` and `PSDReportModuleImageAttribute` are decorated with `AllowMultiple = false`.
|
|
|
|
---
|
|
|
|
## 4. Dependencies
|
|
|
|
### This module depends on:
|
|
|
|
**Prism Framework:**
|
|
- `Prism.Ioc` - `IContainerRegistry`, `IContainerProvider`
|
|
- `Prism.Modularity` - `IModule`, `ModuleAttribute`, `IModuleCatalog`
|
|
- `Prism.Events` - `IEventAggregator`
|
|
- `Microsoft.Practices.Prism.Events` - `IEventAggregator` (legacy)
|
|
- `Microsoft.Practices.Prism.Modularity` - `IModuleCatalog`, `UnityBootstrapper`
|
|
- `Microsoft.Practices.Prism.Regions` - `IRegionManager`, `RegionAdapterMappings`, `Region`, `RegionManager`
|
|
- `Microsoft.Practices.Prism.UnityExtensions` - `UnityBootstrapper`
|
|
|
|
**Unity DI:**
|
|
- `Unity` - `IUnityContainer`
|
|
- `Unity.Lifetime` - `ContainerControlledLifetimeManager`
|
|
- `Microsoft.Practices.Unity` - `IUnityContainer`, `InjectionMember`
|
|
|
|
**DTS Common Libraries:**
|
|
- `DTS.Common` - `AssemblyNames`, `AssemblyInfo`, `eAssemblyGroups`, `eAssemblyRegion`
|
|
- `DTS.Common.Events` - `LoadViewModulEvent`, `LoadViewModulArg`, `AssemblyListNotificationViewer`, `AssemblyListInfo`
|
|
- `DTS.Common.Interface` - `IPSDReportModule`, `IPSDReportMainViewGrid`, `IPSDReportMainViewModel`, `IShellViewModel`, `IDTSViewRegionManager`
|
|
- `DTS.Common.Base` - `TextAttribute`, `ImageAttribute`
|
|
- `DTS.Common.Core.PluginLib` - `PluginManager`, `PluginConfigSectionHandler`, `FilterHashElement`, `DTSViewRegionManager`
|
|
|
|
**WPF/.NET:**
|
|
- `System.Windows` - `DependencyObject`, `DependencyProperty`
|
|
- `System.Windows.Controls` - `ItemsControl`, `ContentControl`, `StackPanel`
|
|
- `System.Windows.Media.Imaging` - `BitmapImage`
|
|
- `System.Configuration` - `ConfigurationManager`
|
|
- `System.ComponentModel.Composition.Hosting` - (imported but not directly used in visible code)
|
|
|
|
### What depends on this module:
|
|
|
|
Not determinable from source alone. The module publishes `LoadViewModulEvent` and `AssemblyListNotificationViewer` events, suggesting other components subscribe to these events.
|
|
|
|
---
|
|
|
|
## 5. Gotchas
|
|
|
|
1. **Dual EventAggregator Imports**: The code imports `IEventAggregator` from both `Prism.Events` (modern) and `Microsoft.Practices.Prism.Events` (legacy). `PSDReportModule` uses the modern namespace while `PSDReportSession` uses the legacy namespace. This could cause runtime issues if they resolve to different instances.
|
|
|
|
2. **Empty Constructor Comment**: `PSDReportSession` has a comment `// ReSharper disable EmptyConstructor` suggesting the empty constructor may be intentional but non-obvious.
|
|
|
|
3. **Bootstrapper Memory Footprint**: The comment in `PSDReportSession` notes: *"It appears that the current bootstrapper loads around 40 MB into memory. To completely unload the bootstrapper would take same research and effort."* There is no mechanism to unload or recreate the bootstrapper.
|
|
|
|
4. **Silent Failure in CreateShell**: `CreateShell()` catches all exceptions, stores the message in a local variable `s` that is never used, and returns `null`. This silently swallows errors.
|
|
|
|
5. **Region Adapter Registration Swallows Errors**: `ConfigureRegionAdapterMappings()` wraps each registration in try/catch with empty catch blocks, silently ignoring duplicate mapping exceptions.
|
|
|
|
6. **Commented-Out Code in ConfigureContainer**: There is commented-out code for conditional registration based on `Standalone` mode, suggesting the registration strategy changed but the old code was preserved.
|
|
|
|
7. **TODO Comment**: `PSDReportSession.CreateSession()` contains `//TODO: review publishPlugins vs base.InitializeModules();` indicating incomplete design review.
|
|
|
|
8. **Inconsistent Naming Convention**: Some private fields use underscore prefix (`_unityContainer`, `_eventAggregator`) while others don't (`Container`). Public properties mix conventions (`_serviceLocator` is public with underscore prefix).
|
|
|
|
9. **Unused Imports**: `System.Runtime.InteropServices.ComTypes` is imported in `Bootstrapper.cs` but the `IStream` type is not used.
|
|
|
|
10. **Module Self-Registration**: `PSDReportModule.Initialize()` registers its own type (`IPSDReportModule` → `PSDReportModule`), which is unusual since the module instance already exists when `Initialize()` is called. |