WPF 插件化架构实践(工业级上位机专篇)

AI 驱动代码审查实战

Claude code-review 插件深度解析,把 AI 智能审查接进 CI/CD 流水线

WPF 插件化架构实践(工业级上位机专篇)

WPF 插件化(Plugin Architecture)是指将应用程序设计成主程序 + 多个独立插件(Plugin/Module)的形式,主程序提供基础框架(Shell、Region、DI容器、导航等),插件可以动态加载、卸载或按需启用,实现高可扩展性、热插拔、现场定制

工业上位机领域,插件化架构特别重要:

  • 不同产线/客户需求差异大(报警规则、趋势曲线、配方管理、MES接口、视觉检测等)。
  • 现场升级时,只需替换或新增插件DLL,无需重新编译整个系统。
  • 支持多人并行开发、独立测试和部署。
  • 长时间运行的系统更容易控制资源和稳定性。

主流实现方式对比(2026年推荐)

方式优点缺点工业推荐场景
Prism + DirectoryModuleCatalog官方支持、与MVVM/Region/DI深度集成、简单可靠隔离性一般(同一AppDomain)首选,大多数工业上位机
Prism + MEF自动发现、Export/Import更灵活配置稍复杂需要更强自动发现时
纯MEF轻量、插件发现强大缺少Prism的导航/Region支持小型插件系统
MAF / AppDomain隔离强隔离、容错性高复杂、性能开销大极高安全需求(极少用)

工业级推荐方案Prism + 动态模块加载(DirectoryModuleCatalog),结合 DI、Region、EventAggregator,形成完整插件化架构。本文以Prism为主,兼顾MEF混合使用。

1. 整体架构设计(推荐结构)

WPFPluginHMI.sln
├── Shell (主程序)
│   ├── App.xaml.cs          ← 配置DI + DirectoryModuleCatalog
│   ├── Shell.xaml           ← 定义多个Region
│   └── ShellViewModel.cs
├── Core                     ← 共享接口、Model、Constants、Converters
├── Infrastructure          ← 全局服务(PLC、Log、Config)
├── Modules                 ← 插件文件夹(运行时)
│   ├── AlarmPlugin          ← 报警插件
│   ├── TrendPlugin          ← 趋势插件
│   ├── RecipePlugin         ← 配方插件
│   └── VisionPlugin         ← 视觉插件(示例)
└── Plugins (可选)           ← 额外插件目录
  • Core:所有插件只依赖接口(IAlarmService、IPlcService等),实现真正解耦。
  • Modules:每个插件是一个独立类库,编译后DLL放入运行目录的 Modules 文件夹。

2. 核心实现步骤

步骤1:主程序配置动态插件加载

App.xaml.cs 中:

protected override void ConfigureModuleCatalog(IModuleCatalog moduleCatalog)
{
    var directoryCatalog = new DirectoryModuleCatalog
    {
        ModulePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Modules")
    };

    // 支持多个目录
    // directoryCatalog.ModulePaths.Add("Plugins");

    moduleCatalog.Add(directoryCatalog);

    // 可混合固定模块(开发调试用)
    // moduleCatalog.AddModule<CoreModule>();
}

步骤2:创建插件(以AlarmPlugin为例)

// AlarmPlugin/AlarmModule.cs
[Module(ModuleName = "AlarmPlugin", OnDemand = false)]
[ModuleDependency("TrendPlugin")]   // 可选依赖
public class AlarmModule : IModule
{
    public void RegisterTypes(IContainerRegistry containerRegistry)
    {
        containerRegistry.RegisterSingleton<IAlarmService, AlarmService>();
        containerRegistry.RegisterForNavigation<AlarmListView, AlarmListViewModel>();
        containerRegistry.RegisterDialog<AlarmConfirmDialog, AlarmConfirmDialogViewModel>();
    }

    public void OnInitialized(IContainerProvider containerProvider)
    {
        var regionManager = containerProvider.Resolve<IRegionManager>();
        regionManager.RegisterViewWithRegion("AlarmRegion", typeof(AlarmListView));

        var alarmService = containerProvider.Resolve<IAlarmService>();
        alarmService.StartMonitoring();   // 启动插件业务
    }
}

步骤3:Shell中定义区域,插件自动填充

<!-- Shell.xaml -->
<Grid>
    <ContentControl prism:RegionManager.RegionName="NavigationRegion" Width="220"/>
    <ContentControl prism:RegionManager.RegionName="ContentRegion" Margin="220,0,0,0"/>
    <ContentControl prism:RegionManager.RegionName="AlarmRegion" />   <!-- 插件可注入此处 -->
</Grid>

步骤4:跨插件通信(EventAggregator)

在Core中定义事件:

public class AlarmOccurredEvent : PubSubEvent<AlarmItem> { }

插件中发布/订阅,实现松耦合联动。

3. 工业级增强实践

  1. Post-build自动复制DLL
    每个插件项目添加:

    xcopy "$(TargetDir)*.dll" "$(SolutionDir)Modules\" /Y /I /D
    
  2. 按需加载(OnDemand)
    重型插件(如视觉处理、报表生成)使用 InitializationMode.OnDemand,在用户点击菜单时通过 IModuleManager.LoadModule("VisionPlugin") 加载。

  3. MEF混合增强发现能力(可选)
    如果需要更强的自动导出/导入,可在Prism中集成MEF容器(Prism.Mef),使用 [Export] / [Import] 特性自动发现插件服务。

  4. 插件安全与容错

    • 订阅 IModuleManager 事件记录加载日志。
    • 单个插件异常不影响主程序(try-catch + 日志)。
    • 生产环境增加DLL签名校验。
  5. 热更新策略

    • 推荐:短暂停机 → 替换DLL → 重启(工业可接受)。
    • 高级:结合AppDomain隔离(复杂,不推荐常规使用)。
  6. 权限与配置

    • 插件可通过配置文件(或DI注入的IConfigService)决定是否启用。
    • 按钮/菜单动态显示基于插件加载状态。

4. 完整工业上位机插件化示例功能

  • AlarmPlugin:实时报警扫描 + 确认弹窗 + 联动Event。
  • TrendPlugin:LiveCharts2趋势曲线,支持多PLC标签。
  • RecipePlugin:配方编辑、下发PLC、版本管理。
  • VisionPlugin:Halcon/OpenCvSharp集成,图像处理插件(OnDemand加载)。

5. 最佳实践总结

  • 接口驱动:Core中定义所有接口,插件只实现接口。
  • Region + 导航:主画面动态切换插件视图。
  • EventAggregator:插件间零耦合通信。
  • DI容器统一管理:所有服务通过Prism容器注入。
  • 动态目录:生产环境必用 DirectoryModuleCatalog
  • 日志与监控:所有插件加载/异常必须记录。
  • 测试策略:每个插件独立单元测试,注入Mock服务。

这种架构让你的WPF上位机像“搭积木”一样灵活:基础Shell + 通用Core + N个插件,根据不同工厂需求快速组合或现场新增功能。

立即实践建议

  1. 基于之前我们学习的Prism项目,创建 Modules 文件夹和2-3个插件项目。
  2. 配置 DirectoryModuleCatalog,实现自动加载。
  3. 在Shell中定义多个Region,让插件视图自动注入。
  4. 添加一个跨插件的EventAggregator事件(例如报警触发趋势刷新)。
  5. 测试:新增/移除一个插件DLL,观察是否热生效(重启后)。

完成这个实践后,你的WPF上位机就具备了真正的工业级插件化能力

下一步推荐(请告诉我你的选择):

  • Prism EventAggregator 详解(跨插件通信,必学)
  • 工业级自定义Shell与Dialog样式(无边框深色工厂风格)
  • PLC实时通信 + 插件化数据绑定实战
  • 完整小型插件化上位机项目代码框架

你当前项目中遇到什么具体问题(动态加载失败、插件间通信、资源释放等)?随时贴代码,我帮你优化。

我们继续把这个插件化架构落地成可直接用于产线的工业上位机!随时告诉我你的进度。🚀

AI 驱动代码审查实战

Claude code-review 插件深度解析,把 AI 智能审查接进 CI/CD 流水线

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

张工在路上

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值