Asp.Net Mvc3.0(MEF依赖注入理论)
前言
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依赖注入理论)的更多相关文章
- Asp.Net Mvc3.0(MEF依赖注入实例)
前言 在http://www.cnblogs.com/aehyok/p/3386650.html前面一节主要是对MEF进行简单的介绍.本节主要来介绍如何在Asp.Net Mvc3.0中使用MEF. 准 ...
- 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, ...
- 基础教程:视图中的ASP.NET Core 2.0 MVC依赖注入
问题 如何在ASP.NET Core MVC Views中注入和使用服务. 解 更新 启动 类来为MVC添加服务和中间件. 添加一项服务 添加一个Controller,返回 ViewResult. 添 ...
- ASP.NET Core中的依赖注入(2):依赖注入(DI)
IoC主要体现了这样一种设计思想:通过将一组通用流程的控制从应用转移到框架之中以实现对流程的复用,同时采用"好莱坞原则"是应用程序以被动的方式实现对流程的定制.我们可以采用若干设计 ...
- ASP.NET Core中的依赖注入(3): 服务的注册与提供
在采用了依赖注入的应用中,我们总是直接利用DI容器直接获取所需的服务实例,换句话说,DI容器起到了一个服务提供者的角色,它能够根据我们提供的服务描述信息提供一个可用的服务对象.ASP.NET Core ...
- ASP.NET Core中的依赖注入(4): 构造函数的选择与服务生命周期管理
ServiceProvider最终提供的服务实例都是根据对应的ServiceDescriptor创建的,对于一个具体的ServiceDescriptor对象来说,如果它的ImplementationI ...
- ASP.NET Core中的依赖注入(5): ServiceProvider实现揭秘 【总体设计 】
本系列前面的文章我们主要以编程的角度对ASP.NET Core的依赖注入系统进行了详细的介绍,如果读者朋友们对这些内容具有深刻的理解,我相信你们已经可以正确是使用这些与依赖注入相关的API了.如果你还 ...
- ASP.NET Core中的依赖注入(5): ServiceProvider实现揭秘 【解读ServiceCallSite 】
通过上一篇的介绍我们应该对实现在ServiceProvider的总体设计有了一个大致的了解,但是我们刻意回避一个重要的话题,即服务实例最终究竟是采用何种方式提供出来的.ServiceProvider最 ...
- ASP.NET Core中的依赖注入(5):ServicePrvider实现揭秘【补充漏掉的细节】
到目前为止,我们定义的ServiceProvider已经实现了基本的服务提供和回收功能,但是依然漏掉了一些必需的细节特性.这些特性包括如何针对IServiceProvider接口提供一个Service ...
随机推荐
- Android应用--QR的生成(二维码)
二维码的定义: 二维码(2-dimensional bar code),是用某种特定的几何图形按一定规律在平面(二维方向上)分布的黑白相间的图形记录数据符号信息的. 在许多种类的二维条码中,常用的码制 ...
- 20165330《网络对抗技术》Exp0 Kali安装
Kali安装 下载地址 Kali官网 VMware 安装步骤 参考在虚拟机中安装kali linux 安装Kali Linux的镜像和VMware 打开VMware,选择文件-新建虚拟机,出现对话框选 ...
- ADO.Net练习1
一. 1.Car表数据查出显示2.请输入要查的汽车名称: 请输入要查的汽车油耗: 请输入要查的汽车马力: static void Main(string[] args) { SqlCo ...
- day--14前端(HTML、CSS)
浏览器相当于客户端,浏览器访问服务端,收到消息之后里面断开,一次请求,一次响应,一次断开. Web框架本质 http://www.cnblogs.com/wupeiqi/articles ...
- net mvc cms
.NET作品集:linux下的.net mvc cms cms程序架构 本程序是主要是用于企业网站开发的,也可以做博客程序,程序是从之前上一篇的.net 博客程序改进过来的,主要技术由webfor ...
- bzoj 1185
题目大意: 给你n个点求最小矩形覆盖. 思路:枚举凸包上的边然后,旋转卡壳找三个相应的为止把矩形的四个点求出来. #include<bits/stdc++.h> #define LL lo ...
- P1417 烹调方案 背包DP
题目背景 由于你的帮助,火星只遭受了最小的损失.但gw懒得重建家园了,就造了一艘飞船飞向遥远的earth星.不过飞船飞到一半,gw发现了一个很严重的问题:肚子饿了~ gw还是会做饭的,于是拿出了储藏的 ...
- H5视频播放器属性与API控件,以及对程序的解释
一:理论 1.视频播放器的格式介绍 视频主要有三部分组成:视频.音频.编码格式 视频格式:avi.rmb.wmv.mpeg4.ogg.webm 2.H5的标签video的简单使用 <video ...
- vue播放video插件vue-video-player实现hls, rtmp播放全过程
1.安装插件 1 npm install vue-video-player -S 2.配置插件 在main.js里添加 1 import VideoPlayer from 'vue-video-pla ...
- 了解java内存模型,看这里就够了
转载请注明作者与出处 程序计数器 线程私有 因为物理cpu并不多,所以jvm是对java里面的线程进行不停的切换执行,因为切换的执行速度太快,所以我们看到是并发执行.所以jvm在切换线程执行后,如果要 ...