Files
2026-04-17 14:55:32 -04:00

12 KiB

source_files, generated_at, model, schema_version, sha256
source_files generated_at model schema_version sha256
DTS Viewer/DTS.Viewer/Settings.cs
DTS Viewer/DTS.Viewer/ExportModule.cs
DTS Viewer/DTS.Viewer/ViewerModule.cs
DTS Viewer/DTS.Viewer/ViewerSession.cs
DTS Viewer/DTS.Viewer/Bootstrapper.cs
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 SettingChanging event before a setting's value is changed. Currently empty implementation.
  • SettingsSavingEventHandler(object sender, CancelEventArgs e) - Handles the SettingsSaving event 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 to true after StartSession() completes.
  • Initialize() - Registers IExportModule to ExportModule with container-controlled lifetime.
  • StartSession() - Resolves IEventAggregator, publishes LoadExportModuleEvent with LoadExportModuleArg, sets SessionStarted = 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 IViewerModule to ViewerModule with container-controlled lifetime.
  • StartSession() - Resolves IEventAggregator, publishes LoadViewModulEvent with LoadViewModulArg, sets SessionStarted = 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 after CreateSession() is called.
  • _serviceLocator (property: IServiceLocator) - Gets the service locator after CreateSession().
  • _eventAggregator (property: IEventAggregator) - Gets the event aggregator after CreateSession().
  • _regionManager (property: IRegionManager) - Gets the region manager after CreateSession().
  • 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 publishes AssemblyListNotificationViewer event.
  • 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 after CreateShell().
  • _EventAggregator (property: IEventAggregator) - Gets the event aggregator after CreateShell().
  • ConfigureContainer() - Registers IViewerMainViewGrid to ViewerMainViewGrid and IViewerMainViewModel to ViewerMainViewModel (singleton).
  • ConfigureRegionAdapterMappings() - Registers region adapters for Selector, ItemsControl, ContentControl, and conditionally StackPanel (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. Returns DependencyObject or null on exception.
  • CreateModuleCatalog() - Returns resolved IModuleCatalog or new AggregateModuleCatalog.
  • ConfigureModuleCatalog() - In standalone mode, reads plugin folders from config section DTS.Common.Core.PluginLib.Config under key viewerPlugins, creates DirectoryModuleCatalog.
  • InitializeModules() - In standalone mode, registers IDTSViewRegionManager to DTSViewRegionManager (singleton), then calls base implementation.

3. Invariants

  1. Bootstrapper Singleton: The ViewerSession._bootstrapper field should only be created once. The CreateBootstrapper method checks for null before creating a new instance.

  2. Session State Consistency: Both ExportModule.SessionStarted and ViewerModule.SessionStarted are false by default and only set to true after StartSession() publishes its respective event.

  3. Module Registration Pattern: Both ExportModule and ViewerModule register themselves as implementations of their respective interfaces using ContainerControlledLifetimeManager (singleton behavior within the container).

  4. Standalone Mode Behavior:

    • ConfigureModuleCatalog() only loads directory-based modules when Standalone == true.
    • InitializeModules() only registers IDTSViewRegionManager when Standalone == true.
    • ConfigureRegionAdapterMappings() only registers StackPanel adapter when Standalone == true.
  5. Attribute Constructor Behavior: Both ExportNameAttribute and ViewerNameAttribute ignore their string parameter in the parameterized constructor, always returning hardcoded "Export" or "Viewer" respectively.

  6. Region Registration: In CreateShell(), regions are only added if they don't already exist (ContainsRegionWithName check).


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:

  • IExportModuleExportModule
  • IViewerModuleViewerModule
  • IViewerMainViewGridViewerMainViewGrid
  • IViewerMainViewModelViewerMainViewModel
  • IDTSViewRegionManagerDTSViewRegionManager

5. Gotchas

  1. Ignored Constructor Parameter: Both ExportNameAttribute(string s) and ViewerNameAttribute(string s) accept a string parameter but completely ignore it, always returning hardcoded values. This is misleading API design.

  2. Mixed Prism Namespace Versions: The code imports from both legacy Microsoft.Practices.Prism.* namespaces and newer Prism.* namespaces. This suggests a migration in progress or dependency on both old and new Prism versions.

  3. Bootstrapper Memory Footprint: The comment in ViewerSession 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 currently no mechanism to unload or recreate the bootstrapper.

  4. Empty Event Handlers: Settings.SettingChangingEventHandler and Settings.SettingsSavingEventHandler have empty implementations with only placeholder comments.

  5. Silent Failures in Region Adapter Registration: ConfigureRegionAdapterMappings() uses empty catch blocks (try { ... } catch { }) when registering region adapters, silently ignoring any registration failures.

  6. Exception Swallowing in CreateShell: The CreateShell() method catches all exceptions, stores the message in a local variable s that is never used, and returns null. This makes debugging shell creation failures difficult.

  7. Commented-Out Code in ConfigureContainer: There is significant commented-out code for conditional view registration based on Standalone mode, suggesting unfinished or experimental functionality.

  8. Redundant Null Check Pattern: In CreateBootstrapper, the method checks _bootstrapper == null twice—once before the try block and once after, throwing an exception if still null. The inner catch already wraps and rethrows with context.

  9. Private Field Naming Convention: Several fields use underscore prefix but are exposed via public properties with different names (e.g., _customConfigPath vs CustomConfigPath), while others like _serviceLocator have public getters but inconsistent naming.

  10. Module Self-Registration: Both ExportModule and ViewerModule register themselves in Initialize(), which is called from RegisterTypes(). This is unusual—typically the container is configured before module initialization, not by the module itself.