乐于分享
好东西不私藏

WPF 插件式上位机开发:MEF 动态模块加载、菜单路由与功能热更新方案

WPF 插件式上位机开发:MEF 动态模块加载、菜单路由与功能热更新方案
一、整体方案介绍
咱们做工业上位机的时候,传统单体 WPF 项目痛点很明显:新增设备调试、数据统计、报警模块就要重新打包发给现场升级,现场必须关闭软件才能更新,产线停机损耗大。用 MEF 做插件化架构就能完美解决,实现模块解耦、自动生成菜单、路由跳转、插件 DLL 替换热更新。
整体架构就三层:
  • 公共接口类库:只定义插件规范、菜单路由实体,主程序和所有插件都引用这个项目,不写业务代码
  • WPF 主宿主程序:负责 MEF 容器初始化、扫描 Plugins 文件夹下所有 dll、加载插件、收集插件注册的菜单、页面路由跳转、监听插件文件变动实现热重载
  • 业务插件类库:每个功能独立一个项目,编译后丢进 Plugins 文件夹就能被主程序识别加载
技术选型
  • 框架:.NET6 WPF(也兼容.NET Framework4.8)
  • 插件框架:原生 MEF System.ComponentModel.Composition
  • 菜单:插件主动注册路由信息,主程序统一渲染侧边菜单栏
  • 热更新:FileSystemWatcher 监听插件目录文件变更,卸载旧插件 + 重建 MEF 容器重新加载
二、第一步:新建公共接口项目 Plugin.Interface

1. 菜单路由实体类 PluginMenuRoute.cs

2. 插件统一规范接口 IPluginModule.cs

三、第二步:WPF 主程序(宿主)核心代码

先 NuGet 安装包:System.ComponentModel.Composition

1. MEF 插件管理器 PluginManager.cs(核心:加载 + 热重载)

2. 插件目录文件监听(热更新监听服务)
3. 主窗口逻辑:菜单绑定 + 路由跳转
主窗口 XAML(侧边菜单 + 内容容器)
四、第三步:创建业务插件(示例:设备测控插件 Plugin.Device)
插件项目引用公共接口 Plugin.Interface,NuGet 同样安装 System.ComponentModel.Composition
1. 设备页面 DeviceControlView.xaml(UserControl)
2. 插件实现类 DevicePlugin.cs(核心导出 MEF)
插件输出配置
插件项目属性 → 生成 → 输出路径设置为:..\WpfMefHost\bin\Debug\net6.0\Plugins\,编译后 dll 自动丢进插件目录。
五、热更新测试流程
  1. 启动主程序,自动加载设备插件,左侧生成【设备控制】菜单,点击正常打开页面
  2. 不关闭上位机软件,直接修改插件页面代码,重新编译插件项目
  3. 因为开启了FileSystemWatcher监听,dll 文件被覆盖瞬间自动触发:
  • 执行旧插件 Unload 释放资源
  • 销毁 MEF 旧容器,重新扫描所有插件
  • 刷新菜单栏,打开页面就是最新修改后的功能,全程无需重启软件
六、扩展优化方向(工控上位机常用)
  1. 增加插件加密校验,防止非法 dll 注入
  2. 新增插件启停配置,后台管理页控制插件启用禁用
  3. 多级菜单路由适配复杂业务系统
  4. 插件依赖注入、日志统一接入 Serilog
  5. 增量更新,只同步变更插件 dll,搭配升级服务端

【源码】
关注评论或者回复【777】得:《WPF 插件式上位机开发|MEF 动态模块加载 + 菜单路由 + 插件热更新 完整版实战文档 + 全套源码》

相关学习资料