Files
DP44/enriched-partialglm/Common/DTS.Common.Property.md

154 lines
6.5 KiB
Markdown
Raw Permalink Normal View History

2026-04-17 14:55:32 -04:00
---
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 `<see cref="PropertiesModule"/>` 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.