--- source_files: - Common/DTS.Common.Property/PropertyModule.cs generated_at: "2026-04-16T11:33:44.285966+00:00" model: "zai-org/GLM-5-FP8" schema_version: 1 sha256: "5ade2343bf1c7a50" --- # Documentation: DTS.Common.Property Module ## 1. Purpose This module serves as a Prism-based plugin module for a modular WPF application. It registers property-related UI components (a view and view-model) with the Unity dependency injection container and provides assembly-level metadata (name, image, region, and group) that the main application uses to display and categorize this component. It is part of a larger plugin architecture where modules self-register at startup. --- ## 2. Public Interface ### `PropertyModule` Class **Signature:** ```csharp [Export(typeof(IModule))] [Module(ModuleName = "Property")] public class PropertyModule : IModule ``` **Constructor:** ```csharp public PropertyModule(IUnityContainer unityContainer) ``` Accepts an injected `IUnityContainer` instance and stores it in a readonly field. **Methods:** ```csharp public void Initialize() ``` Registers the following type mappings with Unity (transient lifetime, not singleton despite the comment): - `IPropertyView` → `PropertyView` - `IPropertyViewModel` → `PropertyViewModel` --- ### `PropertiesNameAttribute` Class **Signature:** ```csharp [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = false)] public class PropertiesNameAttribute : TextAttribute ``` **Constructors:** ```csharp public PropertiesNameAttribute() public PropertiesNameAttribute(string s) ``` Both constructors initialize `_assemblyName` to the hardcoded string `"PropertiesAsssembly"`. **Properties:** ```csharp public override string AssemblyName { get; } ``` Returns the hardcoded assembly name. **Methods:** ```csharp public override Type GetAttributeType() // Returns typeof(TextAttribute) public override string GetAssemblyName() // Returns AssemblyName property ``` --- ### `PropertiesImageAttribute` Class **Signature:** ```csharp [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = false)] public class PropertiesImageAttribute : ImageAttribute ``` **Constructors:** ```csharp public PropertiesImageAttribute() public PropertiesImageAttribute(string s) ``` Both constructors initialize `_img` via `AssemblyInfo.GetImage(AssemblyNames.Property.ToString())`. **Properties:** | Property | Return Type | Value | |----------|-------------|-------| | `AssemblyImage` | `BitmapImage` | Loaded via `AssemblyInfo.GetImage(AssemblyNames.Property.ToString())` | | `AssemblyName` | `string` | `AssemblyNames.Property.ToString()` | | `AssemblyGroup` | `string` | `eAssemblyGroups.Viewer.ToString()` | | `AssemblyRegion` | `eAssemblyRegion` | `eAssemblyRegion.PropertyRegion` | **Methods:** ```csharp public override Type GetAttributeType() // Returns typeof(ImageAttribute) public override BitmapImage GetAssemblyImage() // Returns AssemblyImage property public override string GetAssemblyName() // Returns AssemblyName property public override eAssemblyRegion GetAssemblyRegion() // Returns AssemblyRegion property public override string GetAssemblyGroup() // Returns AssemblyGroup property ``` --- ## 3. Invariants 1. **Single Instance per Assembly**: Both `PropertiesNameAttribute` and `PropertiesImageAttribute` are applied at assembly level with `AllowMultiple = false`, ensuring exactly one instance of each per assembly. 2. **Module Registration Order**: The `Initialize()` method must be called after the Unity container is fully constructed but before any code attempts to resolve `IPropertyView` or `IPropertyViewModel`. 3. **Attribute Base Class Requirements**: Both attribute classes inherit from abstract base classes (`TextAttribute` and `ImageAttribute` respectively) that are not defined in this file but must exist in `DTS.Common.Interface` or another referenced assembly. 4. **Image Resource Availability**: `AssemblyInfo.GetImage()` must be able to locate an image resource keyed by `AssemblyNames.Property.ToString()` at the time the attribute is queried. --- ## 4. Dependencies ### This Module Depends On: | Dependency | Purpose | |------------|---------| | `Microsoft.Practices.Prism.Modularity` | Provides `IModule` interface and `ModuleAttribute` for plugin architecture | | `Microsoft.Practices.Unity` | Provides `IUnityContainer` for dependency injection | | `System.ComponentModel.Composition` | Provides MEF `ExportAttribute` | | `System.Windows.Media.Imaging` | Provides `BitmapImage` for assembly icon | | `DTS.Common.Interface` | Defines `TextAttribute`, `ImageAttribute`, `IPropertyView`, `IPropertyViewModel` | | `AssemblyInfo` (location unclear) | Static utility class with `GetImage()` method | | `AssemblyNames` (enum, location unclear) | Enum containing `Property` value | | `eAssemblyGroups` (enum, location unclear) | Enum containing `Viewer` value | | `eAssemblyRegion` (enum, location unclear) | Enum containing `PropertyRegion` value | | `PropertyView` (location unclear) | Concrete type implementing `IPropertyView` | | `PropertyViewModel` (location unclear) | Concrete type implementing `IPropertyViewModel` | ### What Depends On This Module: - The main application shell, which discovers and loads Prism modules via MEF exports and reads assembly-level attributes for UI display. --- ## 5. Gotchas 1. **Typo in Assembly Name**: `PropertiesNameAttribute` hardcodes `_assemblyName = "PropertiesAsssembly"` with three consecutive 's' characters. This may cause lookup failures if other code expects correct spelling. 2. **Misleading XML Comment**: The constructor XML doc references `` but the actual class name is `PropertyModule` (no 's'). 3. **Comment Inaccuracy**: The comment in `Initialize()` states "Register View & View-Model... as a singleton" but `RegisterType` registers types with transient lifetime by default. To register as singleton, `ContainerControlledLifetimeManager` would be required. 4. **Unused Constructor Parameters**: Both attribute classes accept a `string s` parameter in their constructors but completely ignore it, always using hardcoded values instead. 5. **Side Effects in Property Getters**: The `AssemblyImage` property getter has a side effect (assigning to `_img` field), which violates typical property getter conventions and could cause unexpected behavior if the property is accessed multiple times. 6. **Lazy Initialization Pattern Inconsistency**: The `AssemblyName`, `AssemblyGroup`, and `AssemblyRegion` properties in `PropertiesImageAttribute` assign to their backing fields on every get, making them behave more like methods than properties.