前言

Managed Extensibility Framework(MEF)是.NET平台下的一个扩展性管理框架,它是一系列特性的集合,包括依赖注入(DI)等。MEF为开发人员提供了一个工具,让我们可以轻松的对应用程序进行扩展并且对已有的代码产生最小的影响,开发人员在开发过程中根据功能要求定义一些扩展点,之后扩展人员就可以使用这些扩展点与应用程序交互;同时MEF让应用程序与扩展程序之间不产生直接的依赖,这样也允许在多个具有同样的扩展需求之间共享扩展程序。

MEF方式

MEF 提供一种通过“组合”隐式发现组件的方法。 MEF 组件(称为“部件-Part”)。部件以声明方式同时指定其依赖项(称为“导入-Import”)及其提供的功能(称为“导出-Export”)。

MEF原理上很简单,找出有共同接口的导入、导出。然后找到把导出的实例化,赋给导入。说到底MEF就是找到合适的类实例化,把它交给导入。

使用 MEF 编写的可扩展应用程序会声明一个可由扩展组件填充的导入,而且还可能会声明导出,以便向扩展公开应用程序服务。 每个扩展组件都会声明一个导出,而且还可能会声明导入。 通过这种方式,扩展组件本身是自动可扩展的。

如何声明一个部件-导入和导出

导出”是部件向容器中的其他部件提供的一个值,而“导入”是部件向要通过可用导出满足的容器提出的要求。 在特性化编程模型中,导入和导出是由修饰类或成员使用 Import 和Export 特性声明的。 Export 特性可修饰类、字段、属性或方法,而 Import 特性可修饰字段、属性或构造函数参数。为了使导入与导出匹配,导入和导出必须具有相同的协定。

假设有一个类HomeController,它声明了可以导入插件的类型是ITestRepository。

    public class HomeController : Controller
{
[Import]
public ITestRepository Repository { get; set; }
}

这里有一个类,它声明为导出。类型同样为ITestRepository。

    [Export(typeof(ITestRepository))]
public class TestRepository:ITestRepository
{
public string GetTestString()
{
return "Hello World";
}
}
这样我们使用Repository属性的时候就可以获得到TestRepository的实例。

如何导入多个部件

一般的 ImportAttribute 特性由一个且只由一个 ExportAttribute 填充。 如果有多个导出可用,则组合引擎将生成错误。若要创建一个可由任意数量的导出填充的导入,可以使用 ImportManyAttribute 特性。

一个接口

    public interface ITestRepository
{
string GetTestString();
}

两个实现

    [Export(typeof(ITestRepository))]
public class TestRepository:ITestRepository
{
public string GetTestString()
{
return "Hello World";
}
}
    [Export(typeof(ITestRepository))]
class TextRepository:ITestRepository
{
public string GetTestString()
{
return "Hello World Text";
}
}
        [ImportMany]
public IEnumerable<ITestRepository> Repository { get; set; }

这样调用Repository就可以进行选择了

导入和导出的继承

如果某个类继承自部件,则该类也可能会成为部件。 导入始终由子类继承。 因此,部件的子类将始终为部件,并具有与其父类相同的导入。通过使用 Export 特性的声明的导出不会由子类继承。 但是,部件可通过使用 InheritedExport 特性继承自身。 部件的子类将继承并提供相同的导出,其中包括协定名称和协定类型。 与 Export 特性不同,InheritedExport 只能在类级别(而不是成员级别)应用。 因此,成员级别导出永远不能被继承。

  下面四个类演示了导入和导出继承的原则。 NumTwo 继承自 NumOne,因此 NumTwo 将导入 IMyData。 普通导出不会被继承,因此 NumTwo 将不会导出任何内容。 NumFour 继承自NumThree。 由于 NumThree 使用了 InheritedExport,因此 NumFour 具有一个协定类型为 NumThree 的导出。 成员级别导出从不会被继承,因此不会导出 IMyData。

[Export]
public class NumOne
{
[Import]
public IMyData MyData { get; set; }
} public class NumTwo : NumOne
{
//导入会被继承,所以NumTwo会有导入属性 IMyData //原始的导出不能被继承,所以NumTwo不会有任何导出。所以它不会被目录发现
} [InheritedExport]
public class NumThree
{
[Export]
Public IMyData MyData { get; set; } //这个部件提供两个导出,一个是NumThree,一个是IMyData类型的MyData
} public class NumFour : NumThree
{
//因为NumThree使用了InheritedExport特性,这个部件有一个导出NumThree。 //成员级别的导出永远不会被继承,所以IMydata永远不是导出
}

创建策略

  当部件指定执行导入和组合时,组合容器将尝试查找匹配的导出。 如果它将导入与导出成功匹配,则导入成员将设置为导出的对象的实例。 导出部件的创建策略控制此实例来源于何处。导入和导出都可从值 Shared、NonShared 或 Any 中指定部件的创建策略。 导入和导出的默认值均为 Any。

例如:

[Import(RequiredCreationPolicy = CreationPolicy.Shared)]

声明周期和释放

  由于部件承载于组合容器中,因此其生命周期可能比普通对象更复杂。需要在关闭时执行工作的部件和需要释放资源的部件应照常为 .NET Framework 对象实现 IDisposable。 但是,由于容器创建并维护对部件的引用,因此只有拥有部件的容器才应对其调用 Dispose 方法。 容器本身实现 IDisposable,并且作为 Dispose 中其清理的一部分,它将对拥有的所有部件调用 Dispose。 因此,当不再需要组合容器及其拥有的任何部件时,您应始终释放该组合容器。

  对于生存期很长的组合容器,创建策略为“非共享”的部件的内存消耗可能会成为问题。 这些非共享部件可以多次创建,并且在容器本身被释放之前将不会得到释放。 为了应对这种情况,容器提供了 ReleaseExport 方法。 如果对非共享导出调用此方法,将会从组合容器中移除该导出并将其释放。 仅由移除的导出使用的部件以及树中更深层的诸如此类部件将也会被移除并得到释放。 通过这种方式,不必释放组合窗口本身即可回收资源。

Asp.Net Mvc3.0(MEF依赖注入理论)的更多相关文章

  1. Asp.Net Mvc3.0(MEF依赖注入实例)

    前言 在http://www.cnblogs.com/aehyok/p/3386650.html前面一节主要是对MEF进行简单的介绍.本节主要来介绍如何在Asp.Net Mvc3.0中使用MEF. 准 ...

  2. ADO.NET .net core2.0添加json文件并转化成类注入控制器使用 简单了解 iTextSharp实现HTML to PDF ASP.NET MVC 中 Autofac依赖注入DI 控制反转IOC 了解一下 C# AutoMapper 了解一下

    ADO.NET   一.ADO.NET概要 ADO.NET是.NET框架中的重要组件,主要用于完成C#应用程序访问数据库 二.ADO.NET的组成 ①System.Data  → DataTable, ...

  3. 基础教程:视图中的ASP.NET Core 2.0 MVC依赖注入

    问题 如何在ASP.NET Core MVC Views中注入和使用服务. 解 更新 启动 类来为MVC添加服务和中间件. 添加一项服务 添加一个Controller,返回 ViewResult. 添 ...

  4. ASP.NET Core中的依赖注入(2):依赖注入(DI)

    IoC主要体现了这样一种设计思想:通过将一组通用流程的控制从应用转移到框架之中以实现对流程的复用,同时采用"好莱坞原则"是应用程序以被动的方式实现对流程的定制.我们可以采用若干设计 ...

  5. ASP.NET Core中的依赖注入(3): 服务的注册与提供

    在采用了依赖注入的应用中,我们总是直接利用DI容器直接获取所需的服务实例,换句话说,DI容器起到了一个服务提供者的角色,它能够根据我们提供的服务描述信息提供一个可用的服务对象.ASP.NET Core ...

  6. ASP.NET Core中的依赖注入(4): 构造函数的选择与服务生命周期管理

    ServiceProvider最终提供的服务实例都是根据对应的ServiceDescriptor创建的,对于一个具体的ServiceDescriptor对象来说,如果它的ImplementationI ...

  7. ASP.NET Core中的依赖注入(5): ServiceProvider实现揭秘 【总体设计 】

    本系列前面的文章我们主要以编程的角度对ASP.NET Core的依赖注入系统进行了详细的介绍,如果读者朋友们对这些内容具有深刻的理解,我相信你们已经可以正确是使用这些与依赖注入相关的API了.如果你还 ...

  8. ASP.NET Core中的依赖注入(5): ServiceProvider实现揭秘 【解读ServiceCallSite 】

    通过上一篇的介绍我们应该对实现在ServiceProvider的总体设计有了一个大致的了解,但是我们刻意回避一个重要的话题,即服务实例最终究竟是采用何种方式提供出来的.ServiceProvider最 ...

  9. ASP.NET Core中的依赖注入(5):ServicePrvider实现揭秘【补充漏掉的细节】

    到目前为止,我们定义的ServiceProvider已经实现了基本的服务提供和回收功能,但是依然漏掉了一些必需的细节特性.这些特性包括如何针对IServiceProvider接口提供一个Service ...

随机推荐

  1. 玲珑OJ 1129 - 喵哈哈村的战斗魔法师丶坏坏い月

    1129 - 喵哈哈村的战斗魔法师丶坏坏い月 Time Limit:3s Memory Limit:256MByte Submissions:315Solved:71 DESCRIPTION 坏坏い月 ...

  2. Java第三阶段学习(十、XML学习)

    一.XML学习 1.模拟Servlet执行 在学习完前端及java与数据库后,将进行WEB编程阶段的学习.在WEB编程中,可以通过浏览器访问WEB服务器上的数据.这时WEB服务器就相当于另一台计算机. ...

  3. 配置免SSH

    在要远程登录别人的服务器中生成授权标识:ssh-keygen -t rsa上传至需被免登录的服务器:scp ~/.ssh/id_rsa.pub root@xx.xx.xx.xx:/root/.ssh/ ...

  4. hdu4055

    hdu4055 题意 给出一个长度为 n - 1 的字符串,要求构造一个包含数字 [1, n] 的排列,从第二位开始,'I' 表示当前位数字比前一位大,'D' 表示当前位数字比前一位小,'?' 表示可 ...

  5. SCTF2018-Event easiest web - phpmyadmin

    6月19日的SCTF的web送分题. 打开链接是一个phpmyadmin的登陆界面,尝试用默认账号:root  密码:root登陆 于是直接进去了,首先看下数据库,除了些初始化的库以外,abc这个库比 ...

  6. 循序渐进学.Net Core Web Api开发系列【6】:配置文件appsettings.json

    系列目录 循序渐进学.Net Core Web Api开发系列目录 本系列涉及到的源码下载地址:https://github.com/seabluescn/Blog_WebApi 一.本篇概述 本篇描 ...

  7. Nessus漏洞扫描教程之使用Nmap工具扫描识别指纹

    Nessus漏洞扫描教程之使用Nmap工具扫描识别指纹 Nmap工具的准备工作 当用户对Nessus工具有清晰的认识后,即可使用该工具实施扫描.但是,在扫描之前需要做一些准备工作,如探测网络中活动的主 ...

  8. JavaScript正则表达式在不同浏览器中可能遇到的问题

    这两天在用正则表达式搞一个稍微有点复杂的东西,但是不同浏览器之间的差异可浪费了我不少的人参. 现在我把正则表达式在五大主流浏览器(IE.firefox.Chrome.Safari.Opera,以当前版 ...

  9. 微信小程序swiper高度自适应,swiper的子元素高度不固定

    小程序 swiper 组件默认高度150px,并且如果子元素过高,swiper不会自适应高度 解决方案一: (总体来说不够完美,适合满屏滑动) 如果不是满屏的状态,用scroll-view IOS滑动 ...

  10. STM32F4 HAL Composite USB Device Example : CDC + MSC

    STM32F4 USB Composite CDC + MSC I'm in the process of building a USB composite CDC + MSC device on t ...