Files
XplorePlane/XplorePlane/Doc/硬件层及UI集成技术路线.md
T
zhengxuan.zhang 2a762396d5 #0052 补充依赖
2026-04-01 17:08:27 +08:00

5.7 KiB
Raw Blame History

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 创建前已具备所有依赖。

// 注册 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:

xmlns:views1="clr-namespace:XP.Hardware.RaySource.Views;assembly=XP.Hardware.RaySource"

在主窗口右侧面板顶部(Grid.Row="0",固定高度 250px)放置控件:

<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 中的关键配置项:

<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

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() 中显式从容器解析并释放资源:

var appStateService = bootstrapper.Container.Resolve<IAppStateService>();
appStateService?.Dispose();

var raySourceService = bootstrapper.Container.Resolve<IRaySourceService>();
raySourceService?.Dispose();

确保硬件连接在应用退出时正确断开。