Files
XplorePlane/Doc/RAYSOURCE_VIEW_INTEGRATION_TECHNICAL.md
T

172 lines
5.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# RaySourceOperateView 集成技术路线
## 整体架构
采用 **DLL 直接引用 + Prism DI 容器手动注册 + AutoWireViewModel 自动装配** 的集成方式。
DLL 提供完整的 MVVM 三层(View / ViewModel / Service),主项目负责 DI 注册和 XAML 布局嵌入,数据通过注入的服务接口和 Prism EventAggregator 在两侧流动。
---
## 分层说明
### 1. DLL 引用层
`XP.Hardware.RaySource.dll` 放置于 `Libs/Hardware/` 目录,通过 `.csproj``<Reference HintPath>` 引用。
DLL 内部包含:
| 类型 | 名称 | 说明 |
|------|------|------|
| UserControl | `RaySourceOperateView` | 射线源操作界面 |
| ViewModel | `RaySourceOperateViewModel` | 对应 ViewModel |
| 服务接口/实现 | `IRaySourceService` / `RaySourceService` | 射线源业务逻辑 |
| 工厂 | `IRaySourceFactory` / `RaySourceFactory` | 策略工厂,支持 Comet225/320、Spellman225 |
| 服务 | `IFilamentLifetimeService` | 灯丝寿命管理 |
| 配置模型 | `RaySourceConfig` | 从 App.config 加载的配置 |
---
### 2. DI 注册层(App.xaml.cs → AppBootstrapper
主项目在 `RegisterTypes()` 中**手动注册** DLL 内所有服务,未走 Prism 的 `ConfigureModuleCatalog` 自动模块加载,目的是避免模块加载顺序问题,确保 DryIoc 容器在 Shell 创建前已具备所有依赖。
```csharp
// 注册 ViewModel(供 ViewModelLocator 自动装配)
containerRegistry.Register<XP.Hardware.RaySource.ViewModels.RaySourceOperateViewModel>();
// 注册配置(从 App.config 读取 RaySource:xxx 键值)
var raySourceConfig = XP.Hardware.RaySource.Config.ConfigLoader.LoadConfig();
containerRegistry.RegisterInstance(raySourceConfig);
// 注册核心服务(全部单例)
containerRegistry.RegisterSingleton<IRaySourceFactory, RaySourceFactory>();
containerRegistry.RegisterSingleton<IRaySourceService, RaySourceService>();
containerRegistry.RegisterSingleton<IFilamentLifetimeService, FilamentLifetimeService>();
```
---
### 3. XAML 嵌入层(MainWindow.xaml
通过 XML 命名空间直接引用 DLL 中的 View:
```xml
xmlns:views1="clr-namespace:XP.Hardware.RaySource.Views;assembly=XP.Hardware.RaySource"
```
在主窗口右侧面板顶部(Grid.Row="0",固定高度 250px)放置控件:
```xml
<views1:RaySourceOperateView Grid.Row="0" Grid.ColumnSpan="2" />
```
控件内部已设置 `prism:ViewModelLocator.AutoWireViewModel="True"`,Prism 按命名约定自动从 DI 容器解析 `RaySourceOperateViewModel` 并绑定为 DataContext。
---
### 4. 数据传递路线
数据流分四条路径:
**路径 A:配置数据(启动时,单向下行)**
```
App.config (RaySource:xxx 键值)
→ ConfigLoader.LoadConfig()
→ RaySourceConfig 实例
→ 注入到 RaySourceService / RaySourceOperateViewModel
```
App.config 中的关键配置项:
```xml
<add key="RaySource:PlcIpAddress" value="192.168.1.100" />
<add key="RaySource:MinVoltage" value="20" />
<add key="RaySource:MaxVoltage" value="225" />
<add key="RaySource:StatusPollingInterval" value="500" />
<add key="RaySource:EnableAutoStatusMonitoring" value="true" />
```
**路径 B:用户操作(UI → DLL 服务层)**
```
RaySourceOperateView(按钮点击)
→ RaySourceOperateViewModelCommand 绑定)
→ IRaySourceService.SetVoltageAsync() / TurnOnAsync() / ...
→ IXRaySource(具体策略实现,如 Comet225
→ 硬件通讯(B&R PVI / BR.AN.PviServices.dll
```
**路径 C:状态回传(DLL 服务层 → UI)**
```
硬件状态轮询(StatusPollingInterval = 500ms
→ RaySourceService 内部更新
→ RaySourceOperateViewModel 属性变更(INotifyPropertyChanged
→ RaySourceOperateView 数据绑定自动刷新
同时:
→ AppStateService 订阅 IRaySourceService 事件
→ 更新 RaySourceState(IsOn, Voltage, Power)
→ Dispatcher.BeginInvoke 调度到 UI 线程
→ 其他 ViewModel 通过 IAppStateService 读取全局射线源状态
```
`RaySourceState` 为不可变 record,定义于 `Models/StateModels.cs`
```csharp
public record RaySourceState(
bool IsOn, // 开关状态
double Voltage, // 电压 (kV)
double Power // 功率 (W)
)
{
public static readonly RaySourceState Default = new(false, 0, 0);
}
```
**路径 D:跨模块事件通讯(Prism EventAggregator**
```
DLL 内部发布事件(XP.Hardware.RaySource.Abstractions.Events):
XrayStateChangedEvent — 射线开关状态变化
StatusUpdatedEvent — 实时电压/电流数据
ErrorOccurredEvent — 错误通知
OperationResultEvent — 操作结果回调
主项目任意 ViewModel 订阅示例:
_eventAggregator.GetEvent<StatusUpdatedEvent>().Subscribe(data => { ... });
```
---
### 5. 完整依赖关系
```
RaySourceOperateViewDLL 中的 UserControl
└─ AutoWire → RaySourceOperateViewModelDLL,主项目注册到 DI
├─ IRaySourceService ← 单例,DLL 实现
├─ RaySourceConfig ← App.config 加载
├─ IFilamentLifetimeService ← 单例,DLL 实现
├─ IEventAggregator ← Prism 内置
├─ ILoggerService ← 主项目 LoggerServiceAdapter 适配 Serilog
└─ ILocalizationService ← 主项目注册,DLL 消费
```
---
### 6. 资源释放
`App.OnExit()` 中显式从容器解析并释放资源:
```csharp
var appStateService = bootstrapper.Container.Resolve<IAppStateService>();
appStateService?.Dispose();
var raySourceService = bootstrapper.Container.Resolve<IRaySourceService>();
raySourceService?.Dispose();
```
确保硬件连接在应用退出时正确断开。