151 lines
12 KiB
Markdown
151 lines
12 KiB
Markdown
---
|
||
source_files:
|
||
- Common/DTS.Common/RegionManager/ViewDefinition.cs
|
||
- Common/DTS.Common/RegionManager/IDataProRegionManager.cs
|
||
- Common/DTS.Common/RegionManager/IDTSRegionManager.cs
|
||
- Common/DTS.Common/RegionManager/IDTSViewRegionManager.cs
|
||
- Common/DTS.Common/RegionManager/RegionManagerExtensions.cs
|
||
- Common/DTS.Common/RegionManager/DataProRegionManager.cs
|
||
- Common/DTS.Common/RegionManager/DTSRegionManager.cs
|
||
- Common/DTS.Common/RegionManager/DTSViewRegionManager.cs
|
||
generated_at: "2026-04-16T02:56:51.813821+00:00"
|
||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||
schema_version: 1
|
||
sha256: "9e0ce2fec908c09b"
|
||
---
|
||
|
||
# Region Management Module Documentation
|
||
|
||
## 1. Purpose
|
||
|
||
This module provides a structured abstraction layer over Prism's region management system for a WPF application, enabling consistent view registration, activation, removal, and data refresh operations across regions using dependency injection and MVVM patterns. It defines a `ViewDefinition` class to declaratively specify view-viewmodel pairs and their target regions, and implements three region manager classes (`DataProRegionManager`, `DTSRegionManager`, `DTSViewRegionManager`) that implement dedicated interfaces (`IDataProRegionManager`, `IDTSRegionManager`, `IDTSViewRegionManager`) to handle view lifecycle operations—including initialization, cleanup, and asynchronous operations—while integrating with Unity container resolution, event aggregation for notifications, and shell view model context updates. The module also provides extension methods (`RegionManagerExtensions`) to augment the base `IRegionManager` with utility operations like clearing, activating, and retrieving views by interface type.
|
||
|
||
## 2. Public Interface
|
||
|
||
### `ViewDefinition` Class
|
||
|
||
- **Constructor**:
|
||
`public ViewDefinition(string regionName, Type viewInterfaceType, Type viewModelInterfaceType)`
|
||
Creates a view definition specifying the target region, the interface type of the view to be resolved, and the interface type of the viewmodel to be resolved. The `ViewType` property is commented out and unused.
|
||
|
||
- **Properties**:
|
||
- `public string RegionName { get; }` – The name of the region where the view will be displayed.
|
||
- `public Type ViewInterfaceType { get; }` – The interface type used to resolve the view (e.g., `IViewForMyViewModel`).
|
||
- `public Type ViewModelInterfaceType { get; }` – The interface type used to resolve the viewmodel (e.g., `IMyViewModel`).
|
||
- `private ViewDefinition()` – Private parameterless constructor; not used in public API.
|
||
|
||
### `IDataProRegionManager`, `IDTSRegionManager`, `IDTSViewRegionManager` Interfaces
|
||
|
||
All three interfaces define identical public members (only `IDataProRegionManager` is shown; others are identical in signature):
|
||
|
||
- `void AddView(ViewDefinition viewDefinition, object parameter)`
|
||
Adds a view to its specified region, resolving view and viewmodel via Unity using the types in `viewDefinition`, setting `view.DataContext`, activating the view, and calling `viewModel.Initialize(parameter)` or `viewModel.Initialize()` if `parameter` is null.
|
||
|
||
- `void AddView(ViewDefinition viewDefinition, object parameter, bool allowMultipleInstances)`
|
||
Same as above, but if `allowMultipleInstances` is `false`, attempts to activate an existing view instance (via `ActivateViewIfExists`) and returns early if successful.
|
||
|
||
- `Task AddViewAsync(ViewDefinition viewDefinition, object parameter)`
|
||
Asynchronous version of `AddView(viewDefinition, parameter, false)`.
|
||
|
||
- `Task AddViewAsync(ViewDefinition viewDefinition, object parameter, bool allowMultipleInstances)`
|
||
Asynchronous version of `AddView(viewDefinition, parameter, allowMultipleInstances)`. Uses `InitializeAsync`/`CleanupAsync` where applicable and logs exceptions via `RaiseNotification` event.
|
||
|
||
- `void RemoveView(IBaseViewModel viewModel)`
|
||
Finds all views whose `DataContext` is the given `viewModel` (across all regions), calls `viewModel.Cleanup()`, deactivates and removes each view.
|
||
|
||
- `void RemoveViewByRegionName(string regionName)`
|
||
Clears all views from the specified region using `ClearRegion`.
|
||
|
||
- `void RefreshView(Type interfaceForView, object parameter)`
|
||
Finds all views implementing `interfaceForView` across all regions, calls `viewModel.Cleanup()`, then `viewModel.Initialize(parameter)` or `viewModel.Initialize()`.
|
||
|
||
- `Task RefreshViewAsync(Type interfaceForView, object parameter)`
|
||
Asynchronous version of `RefreshView`, calling `CleanupAsync` and `InitializeAsync`.
|
||
|
||
> **Note**: The three manager interfaces (`IDataProRegionManager`, `IDTSRegionManager`, `IDTSViewRegionManager`) are functionally identical. Their implementations (`DataProRegionManager`, `DTSRegionManager`, `DTSViewRegionManager`) share nearly identical logic, with minor differences in `GetShellViewModelByRegionName` and region-specific shell context handling (e.g., `NavigationRegion` is only handled in `DataProRegionManager`).
|
||
|
||
### `RegionManagerExtensions` Class
|
||
|
||
- `public static void ClearRegion(this IRegionManager regionManager, string regionName)`
|
||
Removes all views in the specified region.
|
||
|
||
- `public static IList<object> GetViews(this IRegionManager regionManager, string regionName, Type interfaceForView)`
|
||
Returns all views in the region that are instances of `interfaceForView`.
|
||
|
||
- `public static object GetView(this IRegionManager regionManager, string regionName, Type interfaceForView)`
|
||
Returns the first view in the region that is an instance of `interfaceForView`.
|
||
|
||
- `public static bool ActivateViewIfExists(this IRegionManager regionManager, string regionName, Type viewType)`
|
||
Activates the first view in the region matching `viewType` (if present), returning `true` if activated. Internally calls `ActivateSingleView`, which also invokes `viewModel.Activated()` on the viewmodel.
|
||
|
||
- `public static void DeactivateViews(this IRegionManager regionManager, string regionName)`
|
||
Deactivates all active views in the region.
|
||
|
||
- `public static void RemoveViews(this IRegionManager regionManager, string regionName)`
|
||
Removes all *active* views in the region (note: only active views, not all views).
|
||
|
||
- `public static void ActivateLastView(this IRegionManager regionManager, string regionName)`
|
||
Activates the last active view in the region; if none are active, activates the last view in the region’s view collection.
|
||
|
||
- `public static void AddViewToRegion(this IRegionManager regionManager, string regionName, object view)`
|
||
Adds a view to the region without activating.
|
||
|
||
- `public static void AddViewToRegionActivate(this IRegionManager regionManager, string regionName, object view)`
|
||
Adds and immediately activates the view.
|
||
|
||
- `public static void RemoveView(this IRegionManager regionManager, object view)`
|
||
Removes the view from *all* regions it belongs to.
|
||
|
||
- `public static void RemoveView(this IRegionManager regionManager, string regionName, object view)`
|
||
Deactivates and removes the view from the specified region.
|
||
|
||
## 3. Invariants
|
||
|
||
- **View-ViewModel Coupling**: Each view must have its `DataContext` set to the resolved viewmodel instance before being added to a region. This is enforced in all `AddView`/`AddViewAsync` implementations.
|
||
|
||
- **Interface-Based Resolution**: Views and viewmodels are resolved using Unity via their *interface* types (`ViewInterfaceType`, `ViewModelInterfaceType`) stored in `ViewDefinition`. Concrete types are never directly referenced in the manager logic.
|
||
|
||
- **Lifecycle Order**: For view initialization, `Initialize`/`InitializeAsync` is called *after* the view is added to the region and activated. For view removal, `Cleanup`/`CleanupAsync` is called *before* deactivation/removal.
|
||
|
||
- **Single Instance Enforcement**: When `allowMultipleInstances` is `false`, `AddViewAsync` attempts to activate an existing view via `ActivateViewIfExists` and returns early if successful—preventing duplicate view instances.
|
||
|
||
- **Region Context Updates**: After view addition, `IShellViewModel.ContextMainRegion` (and `ContextNavigationRegion` in `DataProRegionManager`) is set to the view instance. This implies that `IShellViewModel` must be resolvable and must expose these properties.
|
||
|
||
- **Exception Handling**: All `AddViewAsync`, `RefreshViewAsync`, and `RefreshView` methods catch exceptions and publish them via `RaiseNotification` event using `Utility.GetAllErrorMessages(ex)`.
|
||
|
||
## 4. Dependencies
|
||
|
||
### Module Dependencies
|
||
- **Prism Library**:
|
||
- `Prism.Regions` (`IRegionManager`, `IRegionCollection`, `IRegion`)
|
||
- `Prism.Events` (`IEventAggregator`, `EventBase` for `RaiseNotification`)
|
||
- **Unity Container**: `Unity.IUnityContainer` for DI-based view/viewmodel resolution.
|
||
- **Custom Types**:
|
||
- `DTS.Common.Base.IBaseView`, `DTS.Common.Base.IBaseViewModel` (for `DataContext`, `Initialize`, `Cleanup`, `Activated`, etc.)
|
||
- `DTS.Common.Interface.IShellViewModel` (for `ContextMainRegion`, `ContextNavigationRegion`)
|
||
- `DTS.Common.Events.RaiseNotification`, `DTS.Common.Classes.NotificationContentEventArgs`, `DTS.Common.Utility` (for error reporting)
|
||
- `DTS.Common.RegionNames` (for region name constants like `MainRegion`, `NavigationRegion`)
|
||
|
||
### Module Dependents
|
||
- Any module or layer requiring region management (e.g., shell initialization, module bootstrapping) depends on one of the `IDTS*RegionManager` interfaces.
|
||
- The `RegionManagerExtensions` are used by internal code and other modules to perform region operations beyond the core manager interface.
|
||
|
||
## 5. Gotchas
|
||
|
||
- **`ViewType` Property Missing**: The `ViewDefinition` class has a commented-out `ViewType` property and constructor overload. Only interface types are used for resolution—no concrete view/viewmodel types are supported in the current implementation.
|
||
|
||
- **Redundant Manager Implementations**: `DataProRegionManager`, `DTSRegionManager`, and `DTSViewRegionManager` are nearly identical in implementation. Differences are minimal (e.g., `NavigationRegion` handling only in `DataProRegionManager`). This suggests possible technical debt or legacy branching.
|
||
|
||
- **`GetShellViewModelByRegionName` Incomplete**: All managers have a `GetShellViewModelByRegionName` method that currently only resolves `IShellViewModel` regardless of region. The commented-out logic suggests future expansion (e.g., per-region shell view models), but it is unused in production code.
|
||
|
||
- **`RefreshView` / `RefreshViewAsync` Scope**: These methods iterate over *all* regions to find views matching `interfaceForView`. This may cause unintended refreshes if the same view interface is used in multiple regions.
|
||
|
||
- **`RemoveViews` vs `ClearRegion`**: `RemoveViews` (extension method) only removes *active* views, whereas `ClearRegion` removes *all* views. This distinction may lead to confusion.
|
||
|
||
- **`AddToRegion`/`RequestNavigate` Not Implemented**: All three region manager classes implement `IRegionManager` but throw `NotImplementedException` for many `IRegionManager` members (e.g., `AddToRegion`, `RegisterViewWithRegion`, `RequestNavigate`). These are not part of the intended public API and should not be used.
|
||
|
||
- **Async Initialization Assumption**: `InitializeAsync` and `CleanupAsync` are assumed to exist on `IBaseViewModel`. If a concrete viewmodel only implements synchronous methods, runtime errors will occur.
|
||
|
||
- **`ReferenceEquals` for ViewModel Matching**: `RemoveView` uses `ReferenceEquals` to match viewmodels. This is safe only if viewmodels are singleton-per-region or not shared across views; otherwise, it may fail to find the correct view.
|
||
|
||
- **No Validation of `ViewDefinition` Inputs**: No null checks or validation of `regionName`, `viewInterfaceType`, or `viewModelInterfaceType` in `ViewDefinition` constructor or manager methods—could lead to runtime resolution failures. |