12 KiB
source_files, generated_at, model, schema_version, sha256
| source_files | generated_at | model | schema_version | sha256 | |||||
|---|---|---|---|---|---|---|---|---|---|
|
2026-04-16T10:57:48.975205+00:00 | zai-org/GLM-5-FP8 | 1 | f841428d718c70bf |
DTS.Viewer Module Documentation
1. Purpose
The DTS.Viewer namespace provides the core module infrastructure for a Prism-based WPF viewer application. It implements a modular architecture using Unity dependency injection and Prism's modularity framework, enabling dynamic loading of viewer and export functionality. The module manages application bootstrapping, session lifecycle, plugin discovery, and region-based view composition. It serves as the entry point for initializing the viewer shell, registering view/viewmodel pairs, and coordinating module communication via event aggregation.
2. Public Interface
Settings (DTS.Viewer.Properties)
internal sealed partial class Settings
- Settings() - Constructor with optional event handler registration (currently commented out).
- SettingChangingEventHandler(object sender, SettingChangingEventArgs e) - Handles the
SettingChangingevent before a setting's value is changed. Currently empty implementation. - SettingsSavingEventHandler(object sender, CancelEventArgs e) - Handles the
SettingsSavingevent before settings are saved. Currently empty implementation.
ExportModule
[Module(ModuleName = "Export")]
public class ExportModule : IExportModule
- ExportModule(IUnityContainer unityContainer) - Constructor accepting an injected Unity container.
- SessionStarted (property:
bool) - Indicates whether a session has been started. Set totrueafterStartSession()completes. - Initialize() - Registers
IExportModuletoExportModulewith container-controlled lifetime. - StartSession() - Resolves
IEventAggregator, publishesLoadExportModuleEventwithLoadExportModuleArg, setsSessionStarted = true. - RegisterTypes(IContainerRegistry containerRegistry) - Calls
Initialize(). - OnInitialized(IContainerProvider containerProvider) - Empty implementation.
ExportNameAttribute
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = false)]
public class ExportNameAttribute : TextAttribute
- ExportNameAttribute() - Default constructor, sets
_assemblyName = "Export". - ExportNameAttribute(string s) - Parameterized constructor, ignores parameter and sets
_assemblyName = "Export". - AssemblyName (property:
string) - Returns_assemblyName("Export"). - GetAttributeType() - Returns
typeof(TextAttribute). - GetAssemblyName() - Returns
AssemblyName.
ViewerModule
[Module(ModuleName = "Viewer")]
public class ViewerModule : IViewerModule
- ViewerModule(IUnityContainer unityContainer) - Constructor accepting an injected Unity container.
- SessionStarted (property:
bool) - Indicates whether a session has been started. - Initialize() - Registers
IViewerModuletoViewerModulewith container-controlled lifetime. - StartSession() - Resolves
IEventAggregator, publishesLoadViewModulEventwithLoadViewModulArg, setsSessionStarted = true. - RegisterTypes(IContainerRegistry containerRegistry) - Calls
Initialize(). - OnInitialized(IContainerProvider containerProvider) - Empty implementation.
ViewerNameAttribute
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = false)]
public class ViewerNameAttribute : TextAttribute
- ViewerNameAttribute() - Default constructor, sets
_assemblyName = "Viewer". - ViewerNameAttribute(string s) - Parameterized constructor, ignores parameter and sets
_assemblyName = "Viewer". - AssemblyName (property:
string) - Returns_assemblyName("Viewer"). - GetAttributeType() - Returns
typeof(TextAttribute). - GetAssemblyName() - Returns
AssemblyName.
ViewerSession
public class ViewerSession
- Container (property:
IUnityContainer) - Gets the Unity container afterCreateSession()is called. - _serviceLocator (property:
IServiceLocator) - Gets the service locator afterCreateSession(). - _eventAggregator (property:
IEventAggregator) - Gets the event aggregator afterCreateSession(). - _regionManager (property:
IRegionManager) - Gets the region manager afterCreateSession(). - CustomConfigPath (property:
string) - Gets/sets custom configuration path for plugin loading. - ViewerSession() - Empty constructor.
- CreateSession(bool standalone, string customConfigPath = "") - Creates the bootstrapper, initializes container/services, loads plugins via
PluginManager, and publishesAssemblyListNotificationViewerevent. - Terminate() - Called during JMPS shutdown. Empty implementation.
Bootstrapper
public class Bootstrapper : UnityBootstrapper
- Bootstrapper(bool standalone, string customConfigPath = "") - Constructor accepting standalone mode flag and optional custom config path.
- Standalone (property:
bool) - Gets/sets whether running in standalone mode. - CustomConfigPath (property:
string) - Gets/sets custom configuration path. - _ServiceLocator (property:
IServiceLocator) - Gets the service locator afterCreateShell(). - _EventAggregator (property:
IEventAggregator) - Gets the event aggregator afterCreateShell(). - ConfigureContainer() - Registers
IViewerMainViewGridtoViewerMainViewGridandIViewerMainViewModeltoViewerMainViewModel(singleton). - ConfigureRegionAdapterMappings() - Registers region adapters for
Selector,ItemsControl,ContentControl, and conditionallyStackPanel(standalone only). Uses try/catch to ignore already-registered mappings. - CreateShell() - Creates the main shell, resolves
IViewerMainViewModel, registers regions, sets DataContext, and initializes the view model. ReturnsDependencyObjectornullon exception. - CreateModuleCatalog() - Returns resolved
IModuleCatalogor newAggregateModuleCatalog. - ConfigureModuleCatalog() - In standalone mode, reads plugin folders from config section
DTS.Common.Core.PluginLib.Configunder keyviewerPlugins, createsDirectoryModuleCatalog. - InitializeModules() - In standalone mode, registers
IDTSViewRegionManagertoDTSViewRegionManager(singleton), then calls base implementation.
3. Invariants
-
Bootstrapper Singleton: The
ViewerSession._bootstrapperfield should only be created once. TheCreateBootstrappermethod checks for null before creating a new instance. -
Session State Consistency: Both
ExportModule.SessionStartedandViewerModule.SessionStartedarefalseby default and only set totrueafterStartSession()publishes its respective event. -
Module Registration Pattern: Both
ExportModuleandViewerModuleregister themselves as implementations of their respective interfaces usingContainerControlledLifetimeManager(singleton behavior within the container). -
Standalone Mode Behavior:
ConfigureModuleCatalog()only loads directory-based modules whenStandalone == true.InitializeModules()only registersIDTSViewRegionManagerwhenStandalone == true.ConfigureRegionAdapterMappings()only registersStackPaneladapter whenStandalone == true.
-
Attribute Constructor Behavior: Both
ExportNameAttributeandViewerNameAttributeignore their string parameter in the parameterized constructor, always returning hardcoded "Export" or "Viewer" respectively. -
Region Registration: In
CreateShell(), regions are only added if they don't already exist (ContainsRegionWithNamecheck).
4. Dependencies
External Dependencies (Imports)
| Namespace | Purpose |
|---|---|
DTS.Common.Events |
Event types: LoadExportModuleEvent, LoadViewModulEvent, AssemblyListNotificationViewer |
DTS.Common.Interface |
Interfaces: IExportModule, IViewerModule, IViewerMainViewGrid, IViewerMainViewModel, IShellViewModel, IDTSViewRegionManager |
DTS.Common.Core.PluginLib |
PluginManager, PluginConfigSectionHandler, FilterHashElement, AssemblyListInfo |
DTS.Common.Base |
TextAttribute base class |
Prism.Events / Microsoft.Practices.Prism.Events |
IEventAggregator, event base classes |
Prism.Ioc |
IContainerRegistry, IContainerProvider |
Prism.Modularity / Microsoft.Practices.Prism.Modularity |
IModule, IModuleCatalog, ModuleAttribute, AggregateModuleCatalog, DirectoryModuleCatalog |
Prism.Regions / Microsoft.Practices.Prism.Regions |
IRegionManager, Region, RegionAdapterMappings, region adapters |
Unity / Microsoft.Practices.Unity |
IUnityContainer, ContainerControlledLifetimeManager, InjectionMember |
Microsoft.Practices.ServiceLocation |
IServiceLocator, ServiceLocator |
System.Configuration |
ConfigurationManager, configuration section handling |
System.ComponentModel.Composition.Hosting |
MEF composition support |
Downstream Dependencies
The following types are registered by this module and expected to be consumed by other components:
IExportModule→ExportModuleIViewerModule→ViewerModuleIViewerMainViewGrid→ViewerMainViewGridIViewerMainViewModel→ViewerMainViewModelIDTSViewRegionManager→DTSViewRegionManager
5. Gotchas
-
Ignored Constructor Parameter: Both
ExportNameAttribute(string s)andViewerNameAttribute(string s)accept a string parameter but completely ignore it, always returning hardcoded values. This is misleading API design. -
Mixed Prism Namespace Versions: The code imports from both legacy
Microsoft.Practices.Prism.*namespaces and newerPrism.*namespaces. This suggests a migration in progress or dependency on both old and new Prism versions. -
Bootstrapper Memory Footprint: The comment in
ViewerSessionnotes: "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 currently no mechanism to unload or recreate the bootstrapper. -
Empty Event Handlers:
Settings.SettingChangingEventHandlerandSettings.SettingsSavingEventHandlerhave empty implementations with only placeholder comments. -
Silent Failures in Region Adapter Registration:
ConfigureRegionAdapterMappings()uses empty catch blocks (try { ... } catch { }) when registering region adapters, silently ignoring any registration failures. -
Exception Swallowing in CreateShell: The
CreateShell()method catches all exceptions, stores the message in a local variablesthat is never used, and returnsnull. This makes debugging shell creation failures difficult. -
Commented-Out Code in ConfigureContainer: There is significant commented-out code for conditional view registration based on
Standalonemode, suggesting unfinished or experimental functionality. -
Redundant Null Check Pattern: In
CreateBootstrapper, the method checks_bootstrapper == nulltwice—once before the try block and once after, throwing an exception if still null. The inner catch already wraps and rethrows with context. -
Private Field Naming Convention: Several fields use underscore prefix but are exposed via public properties with different names (e.g.,
_customConfigPathvsCustomConfigPath), while others like_serviceLocatorhave public getters but inconsistent naming. -
Module Self-Registration: Both
ExportModuleandViewerModuleregister themselves inInitialize(), which is called fromRegisterTypes(). This is unusual—typically the container is configured before module initialization, not by the module itself.