.NET中间件 -- MEF2

article/2025/9/15 0:33:03

MEF官方解释 : MEF(Managed Extensibility Framework)是一个用于创建可扩展的轻型应用程序的库。 应用程序开发人员可利用该库发现并使用扩展,而无需进行配置。 扩展开发人员还可以利用该库轻松地封装代码,避免生成脆弱的硬依赖项。 通过 MEF,不仅可以在应用程序内重用扩展,还可以在应用程序之间重用扩展。

作用:  (1) 使用MEF是为了提高程序的可扩展性。MEF会根据指定的导入导出自动去发现匹配的扩展,获取到相应类型的对象,不需要进行复杂的程序配置

         (2) 程序设计有几个原则,“高内聚,低耦合”就是其中一个。使用MEF可以帮助我们减少内库之间的耦合。

NuGet安装MEF2, 包名是 Microsoft.Composition,适用于 .NET Framework 4.5 及以上,.NET Core 和各种 .NET 移动平台

使用说明:添加引用System.Composition,MEF 完全使用特性来管理容器中的依赖,Import/Export:在类型上标记 [Export] 可以让容器发现这个类型。[Export] 允许带两个参数,一个契约名称,一个契约类型。在 [Import] 的时候,相同的契约名称会被注入

示例:

1. 简单使用

类ModelA实现接口IModel,ModelA添加特性[Export(typeof(IModel))],创建Container容器管理依赖

    namespace MEF.Interface{public interface IModel{void Do();}    }namespace MEF.ViewModels{[Export(typeof(IModel))]public class ModelA : IModel{public void Do(){Console.WriteLine(MethodBase.GetCurrentMethod().DeclaringType.FullName);}}}public class Container{private static Container _instance;public static Container Instance{get => _instance ?? (_instance = new Container());}public ContainerConfiguration Composition { get; set; }private Container(){//在Program类所在的程序集中,直接或间接加了 [Export] 特性的类都将被此依赖容器管理。Composition = new ContainerConfiguration().WithAssembly(typeof(Program).Assembly);}}class Program{public static IModel Model { get; set; }static void Main(string[] args){//创建容器var container= Container.Instance.Composition.CreateContainer();//获取实现IModel接口且有[Export(typeof(IModel))]标记的类的对象Model = container.GetExport<IModel>();Model.Do();Console.ReadKey();}}

输出:

 

2. 实现接口IModel的类有多个时,ModelA , ModelB

var models = container.GetExports<IModel>().ToArray();foreach (var item in models)
{item.Do();
}

输出:

3. 通过构造函数注入,在构造函数添加特性[ImportingConstructor]

    public interface IView{void Show();}    [Export(typeof(IView))]public class ViewA : IView{public Imodel Model { get; set;}[ImportingConstructor]public ViewA(IModel model)  //实现IModel的类必须添加[Export]特性{Model = model;  //通过构造函数注入对象}public void Show(){Console.WriteLine(MethodBase.GetCurrentMethod().DeclaringType.FullName);Model.Do();}}var view= container.GetExports<IView>().FirstOrDefault();view.Show();

4. [ImportMany]导入多个实现了该接口的对象

    [Export(typeof(IView))]public class ViewA : IView{public ObservableCollection<IModel> Model { get; }[ImportingConstructor]public ViewA([ImportMany]IEnumerable<IModel> model)  //importmany:导入多个实现了该接口的类{Model = new ObservableCollection<IModel>(model);}public void Show(){Console.WriteLine(MethodBase.GetCurrentMethod().DeclaringType.FullName);foreach (var item in Model){item.Do();}}}

输出:

5. 当实现接口的类有多个时,为方便管理,使用契约名称来筛选要导出导入的对象

 [Export("ModelA",typeof(IModel))] 参数1:契约名称(按需求自己起)  作用:在Import的时候,添加契约,会导入指定含有契约名称的类,契约名可以重复(此时导入多个),这样一来,我们就可以用契约名给类进行分类,导入时可以根据契约名来导入。

    public class ExtendA : IExtend[Export("ModelA",typeof(IModel))]public class ModelA : IModel{public void Do(){Console.WriteLine(MethodBase.GetCurrentMethod().DeclaringType.FullName);}}//契约名称为空,则不能发现指定了契约名称的ModelAvar models = container.GetExports<IModel>().ToArray();//写入指定的契约名称,只能发现指定了相同契约名称的导出var models = container.GetExports<IModel>("ModelA").ToArray();

 6. 导出的类添加特性 [Shared]  ,使导出的类共享实例(实例只有一个)

    public interface IExtend{void Init();int Num { get; set; }}[Shared]  [Export("ext",typeof(IExtend))]   public class ExtendA : IExtend{public void Init(){Num += 10;Console.WriteLine(MethodBase.GetCurrentMethod().DeclaringType.FullName);Console.WriteLine($"Num :  {Num}");}public int Num { get; set; }}var Extend_1 = container.GetExport<IExtend>("ext");Extend_1.Init();var Extend_2 = container.GetExport<IExtend>("ext");Extend_2.Init();

通过Num的值的变化简单说明共享实例,

不添加[Shared],输出:

添加[Shared],输出:

 7. Lazy<>延迟初始化

    [Export(typeof(IView))]public class ViewB : IView{/** Lazy<>延迟初始化:仅仅当对象第一次使用的时候,再初始化,如果一直没有调用,那就不初始化* 应用场景:1.对象创建成本高且程序可能不会使用它  2. 对象创建成本高,且希望将其创建推迟到其他高成本操作完成后* 只有在Lazy变量的Value属性被首次访问时对象才会真正的创建,该属性只读,因此仅有get访问器*/private readonly Lazy<IExtend> _extend;  public IExtend Extend => _extend.Value;[ImportingConstructor]  //构造函数导入public ViewB([Import("ext")] Lazy<IExtend> extend)   //无锲约名称时,里面的import可以不写{_extend = extend;}public void Show(){Console.WriteLine(MethodBase.GetCurrentMethod().DeclaringType.FullName);Extend.Init();}}

 

 参考:

【1】Managed Extensibility Framework (MEF) | Microsoft Docs

【2】.NET Core 和 .NET Framework 中的 MEF2 - walterlv - 博客园 (cnblogs.com)

【3】C#进阶系列——MEF实现设计上的“松耦合”(一) - 懒得安分 - 博客园 (cnblogs.com)


http://chatgpt.dhexx.cn/article/Z98f5N33.shtml

相关文章

C# MEF入门讲解

MEF入门之不求甚解&#xff0c;但力求简单能讲明白(一) 起因&#xff1a;工作需要针对不同类型的文件做不同的处理。打个比方&#xff0c;txt文件&#xff0c;直接打印&#xff0c;doc文件&#xff0c;直接发email&#xff0c;jpg文件&#xff0c;上传xxx相册站点。 其实这个问…

Mef

hint&#xff1a; 宿主和插件都引用协议程序集 0-------------------------------------------- 从mef的角度来看&#xff0c;根本不需要接口协议&#xff0c; 协议可以是简单的字符串。 插件部分 [Export("cccd")] public class Foo{ public string Bar(){ retu…

MEF基础

https://www.cnblogs.com/yk123/p/5350133.html 之前公司里用到了一个叫MEF的东西&#xff0c;说来惭愧一直只管写代码却不曾理解MEF框架为何物&#xff0c;今天就来学习一下&#xff0c;这是一篇迟到了不知多久的博客。 --------------------------------------------------…

C# 依赖注入 MEF

1、什么是MEF 先来看msdn上面的解释&#xff1a;MEF(Managed Extensibility Framework)是一个用于创建可扩展的轻型应用程序的库。 应用程序开发人员可利用该库发现并使用扩展&#xff0c;而无需进行配置。 扩展开发人员还可以利用该库轻松地封装代码&#xff0c;避免生成脆弱…

MEF 基础简介 一

前言 小编菜鸟级别的程序员最近感慨颇多&#xff0c;经历了三五春秋深知程序路途遥远而我沧海一粟看不到的尽头到不了的终点何处是我停留的驿站。说了段废话下面进入正题吧&#xff01; 什么是MEF&#xff1f; MEF&#xff1a;全称Managed Extensibility Framework&#xff08;…

MEF插件式开发

一、MEF 简介 1、 Managed Extensibility Framework简称MEF&#xff0c;是WPF中的一种插件式开发的框架。其开发程序的主要优点如下&#xff1a; 易于将复杂程序进行拆分成不同的功能模块&#xff0c;然后进行多团队的协作。将各个功能编译成dll的形式提供给主程序&#xff0…

C#可扩展编程之MEF学习笔记(一):MEF简介及简单的Demo

在文章开始之前&#xff0c;首先简单介绍一下什么是MEF&#xff0c;MEF,全称Managed Extensibility Framework&#xff08;托管可扩展框架&#xff09;。单从名字我们不难发现&#xff1a;MEF是专门致力于解决扩展性问题的框架&#xff0c;MSDN中对MEF有这样一段说明&#xff1…

【C#进阶系列】【MEF框架(一)】

C#进阶系列 第一章 【C#进阶系列】【MEF框架&#xff08;一&#xff09;】 文章目录 C#进阶系列前言一、MEF介绍二、为什么要用MEF三、MEF的概念四、使用示例五、MEF框架的好处六、源码链接总结 前言 这里对MEF作了基本的介绍&#xff0c;包括使用了一个特定场景&#xff08;…

【虚拟化生态平台】平台架构图思路和实现细节

设计思路 我需要一个内网生态&#xff0c;通过一个nginx访问到我所有的资源&#xff0c;内部实现细节我不关心&#xff0c;那么就需要一个nginx服务器来负载所有的服务服务器太多了&#xff0c;我不想一个个的记录ip去登录&#xff0c;那我就需要一个跳板机来记录我的服务器&a…

ARM平台的虚拟化介绍

本篇博文主要介绍虚拟化的基本思想以及在arm平台如何做虚拟化&#xff0c;arm提供的硬件feature等等。 虚拟化技术简介 虚拟化技术 虚拟化是一个概念&#xff0c;单从这个概念的角度来看&#xff0c;只要是用某一种物品去模拟另一种物品都可以称为虚拟化&#xff0c;甚至于有…

ARMv8虚拟化

1 概述 2 虚拟化简介 3 AArch64虚拟化 4 Stage-2地址转换 5 指令的陷入和模拟 6 虚拟化异常 7 虚拟化通用定时器 8 虚拟化主机扩展 9 嵌套虚拟化 10 安全空间的虚拟化 11 虚拟化的成本 12 小测验 13 其它参考文章 14 接下来的计划 1 概述 本文描述了ARMv8-64的虚…

虚拟化服务器环境搭建方案,虚拟化环境建设方案

虚拟化环境建设方案 市场背景: 随着IT技术的飞速发展,基础传统IT架构模式下的应用规模扩大,需要更多的服务器来支持业务的发展,同时出现了如下几个问题: 1.资源利用率低、闲置率高,运行效率低 2.应急处理响应时间慢、服务保障差 3.运行维护成本高 虚拟化的出现很好的解决…

搭建vmware虚拟化平台的基础配置,以及Hadoop平台的搭建

需要准备的东西&#xff1a; vmware workstations centos.iso hadoop3.3.0 mobaxterm/xshell/pietty/winscp jdk的tar包 第一步 &#xff1a; 安装centos操作系统 第二步 &#xff1a; 克隆虚拟机&#xff08;也可以在hadoop安装后再克隆&#xff09; 我们这里需要选择完整克隆…

WSL2 请启用虚拟机平台 Windows 功能并确保在 BIOS 中启用虚拟化

bcdedit /set hypervisorlaunchtype autoC:\WINDOWS\system32>bcdedit /set hypervisorlaunchtype auto 操作成功完成。

嵌入式虚拟化平台jailhouse踩坑笔记

目录 简介 相关论文 架构 jailhouse的应用示例 jailhouse 官方demo jailhouse的运行 jailhouse none-root cell中挂载nfs作为根目录启动linux 注意事项 jailhouse的配置 1.cell配置文件简介 2. cell文件的生成过程 2. .c配置文件内容解析 QEMU中实现jailhouse的…

搭建华为FusionCompute虚拟化平台

最小实验要求&#xff1a;两台服务器 1、通过BMC口安装CNA操作系统 远程光驱安装CNA&#xff0c;需要设置服务器从远程光驱启动&#xff0c;然后进入BIOS可以查看BMC控制台的用户名和密码&#xff0c;以及IP&#xff0c;一般服务器都默认有。然后登陆BMC的控制台&#xff0c;进…

服务器虚拟化 涉密,面向高安全服务器虚拟化领域应用研制的安全保密虚拟化平台...

中标麒麟服务器虚拟化系统是基于中标麒麟虚拟化平台软件V7&#xff0c;面向高安全服务器虚拟化领域应用研制的安全保密虚拟化平台&#xff1b;产品通过国家保密科技测评中心基于《涉密信息系统服务器虚拟化和桌面虚拟化产品安全保密技术要求》(BMB30-2017)的安全性检测。支持海…

VA虚拟平台十大亮点

VA虚拟平台十大亮点 一、自适应多种安装环境、并可以手动调整二、兼容互联网上主流动态域名自动连接&#xff0c;并有自主的动态域名解析。三、系统稳定性有效保障和看门狗机制四、高级参数最大限度保障程序兼容性五、智能打印-动态调整、实时预览、多页排版、自动打印六、向下…

Linux虚拟化平台检测

如果要找出 Linux 系统运行在虚拟化平台中还是硬件服务器上&#xff0c;有多种方式可供大家选择&#xff0c;这主要取决于你的 hypervisor 或 container 环境。不同的虚拟化或容器技术会在其实例中引入不同的识别指纹&#xff0c;如&#xff1a;处理器厂商、特殊的 /proc 文件或…

虚拟化平台PVE(ProxmoxVirtual Environment)安装部署

PVE是一个完整的企业虚拟化开源平台。通过内置的web界面&#xff0c;可以轻松地管理虚拟机和容器、软件定义的存储和网络、高可用性集群和多个开箱即用的工具。 官方&#xff1a;Proxmox - Powerful open-source server solutions 部署前准备 1.下载镜像&#xff0c;并刻录到U…