当前位置: 首页 > news >正文

在 MEF 中处理多个 Tab 页对应同一模块的不同实例

在 MEF 中处理多个 Tab 页对应同一模块的不同实例时,关键在于控制 实例生命周期导出/导入策略。以下是具体解决方案:


1. 基础场景实现

需求:每个 Tab 页需要独立的 ModuleA 实例
// 模块定义(标记为非共享实例)
[Export(typeof(IModule))]
[PartCreationPolicy(CreationPolicy.NonShared)] // 关键点:每次请求新实例
public class ModuleA : IModule {public string TabId { get; } = Guid.NewGuid().ToString();
}// Tab 页容器类
public class TabPage {[Import(typeof(IModule))]public IModule Module { get; set; } // 每个Tab会注入不同的实例
}// 主程序使用
var tabs = new List<TabPage>();
for (int i = 0; i < 5; i++) {var tab = new TabPage();container.ComposeParts(tab); // 每次都会创建新的ModuleA实例tabs.Add(tab);
}

2. 进阶场景:带参数的实例化

需求:每个 Tab 页需要定制化的模块实例
// 使用 ExportFactory 实现按需创建
[Export]
public class TabManager {[Import]public ExportFactory<IModule> ModuleFactory { get; set; }public IModule CreateTabModule(string title) {var export = ModuleFactory.CreateExport();var module = export.Value;module.Title = title; // 假设IModule有Title属性return module;}
}// 模块定义
[Export(typeof(IModule))]
[PartCreationPolicy(CreationPolicy.NonShared)]
public class ModuleA : IModule {public string Title { get; set; }
}

3. 生命周期对比

方式特点
CreationPolicy.Shared单例模式(所有 Tab 共享同一实例)
CreationPolicy.NonShared每次请求新实例(适合多 Tab 场景)
ExportFactory更精细的控制,可在运行时传递参数

4. 完整 WPF TabControl 集成示例

// MainWindow.xaml.cs
[Export]
public partial class MainWindow : Window {[ImportMany]public IEnumerable<ExportFactory<IModule, IModuleMetadata>> ModuleFactories { get; set; }private void AddTab(string moduleType) {var factory = ModuleFactories.First(f => f.Metadata.ModuleType == moduleType);var export = factory.CreateExport();var tabItem = new TabItem {Header = export.Metadata.Title,Content = new ModuleView { DataContext = export.Value }};tabControl.Items.Add(tabItem);}
}// 模块定义(带元数据)
[Export(typeof(IModule))]
[ExportMetadata("ModuleType", "Chart")]
[ExportMetadata("Title", "数据分析模块")]
[PartCreationPolicy(CreationPolicy.NonShared)]
public class ChartModule : IModule { /*...*/ }

5. 关键问题解决方案

Q: 如何确保模块资源释放?
// 使用 ExportLifetimeContext 管理生命周期
var export = moduleFactory.CreateExport();
try {var module = export.Value;// 使用模块...
} finally {export.Dispose(); // 释放模块及其依赖
}
Q: 不同 Tab 间需要共享某些服务?
// 将共享服务标记为Shared
[Export(typeof(ISharedService))]
[PartCreationPolicy(CreationPolicy.Shared)]
public class SharedService : ISharedService { /*...*/ }// 模块类通过Import自动获取同一实例
public class ModuleA {[Import]public ISharedService SharedService { get; set; }
}

6. MEF2 (System.Composition) 实现

// 使用 MEF2 的共享范围控制
[Export(typeof(IModule)), Shared(Boundaries.TabBoundary)]
public class TabScopedModule : IModule { /*...*/ }// 创建作用域
using var tabScope = container.CreateBoundaryScope(Boundaries.TabBoundary);
var module = tabScope.GetExport<IModule>();

通过以上方式,MEF 可以完美支持多 Tab 场景下的模块实例管理。如果需要更具体的实现细节(如 MVVM 模式集成或异步加载),可以进一步探讨。

http://www.dtcms.com/a/309653.html

相关文章:

  • python进程、线程、协程
  • 第二十三天(数据结构:链表补充【希尔表】)
  • 海外商城 app 系统架构分析
  • 电子电气架构 --- 软件项目变更管理
  • Corrosion2靶机攻略
  • 第七章 愿景12 小萍分享《人性的弱点》
  • 大模型推理引擎总结
  • AIGC(生成式AI)试用 35 -- 用AI解析句子结构
  • 力扣-最大单词长度乘积
  • 守护数字核心:主机安全的重要性与全方位防护指南
  • .NET 如何实现ChatGPT的Stream传输
  • HCLP--ospf综合实验
  • Qt大数据监控平台
  • Ant Design Vue notification自定义
  • 算法题——数组
  • Master Prompt:AI时代的万能协作引擎
  • html5和vue区别
  • 使用 Scikit-LLM 进行零样本和少样本分类
  • spring boot 使用mybatis简单连接数据库+连表查询
  • 向量投影计算,举例说明
  • LangChain详解
  • codex体验失败记录
  • Web3.0如何塑造互联网的未来
  • [echarts]基础地图
  • 北极圈金融科技革命:奥斯陆证券交易所的绿色跃迁之路 ——从Visma千倍增长到碳信用衍生品,解码挪威资本市场的技术重构
  • 数据结构(11)栈和队列算法题 OVA
  • 基于OpenCV的cv2.solvePnP方法实现头部姿态估计
  • AJAX快速入门 - 四个核心步骤
  • DB-GPT 0.7.3 版本更新:支持Qwen3 Embedding和Reranker模型、支持知识库自定义检索策略等
  • 从Web2.0到Web3.0:社交参与方式的重塑与延伸