前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Asp.Net Mvc3.0(MEF依赖注入理论)

Asp.Net Mvc3.0(MEF依赖注入理论)

作者头像
aehyok
发布于 2018-09-11 05:11:41
发布于 2018-09-11 05:11:41
71900
代码可运行
举报
文章被收录于专栏:技术博客技术博客
运行总次数:0
代码可运行

前言

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

MEF方式

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

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

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

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

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

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    public class HomeController : Controller
    {
        [Import]
        public ITestRepository Repository { get; set; }
    }

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    [Export(typeof(ITestRepository))]
    public class TestRepository:ITestRepository
    {
        public string GetTestString()
        {
            return "Hello World";
        }
    }
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
这样我们使用Repository属性的时候就可以获得到TestRepository的实例。

如何导入多个部件

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

一个接口

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    public interface ITestRepository
    {
        string GetTestString();
    }

两个实现

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    [Export(typeof(ITestRepository))]
    public class TestRepository:ITestRepository
    {
        public string GetTestString()
        {
            return "Hello World";
        }
    }
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    [Export(typeof(ITestRepository))]
    class TextRepository:ITestRepository
    {
        public string GetTestString()
        {
            return "Hello World Text";
        }
    }
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
        [ImportMany]
        public IEnumerable<ITestRepository> Repository { get; set; }

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

导入和导出的继承

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

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[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。

例如:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[Import(RequiredCreationPolicy = CreationPolicy.Shared)]

声明周期和释放

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

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

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2013-10-26 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
I/O多路复用select/poll/epoll
早期操作系统通常将进程中可创建的线程数限制在一个较低的阈值,大约几百个。因此, 操作系统会提供一些高效的方法来实现多路IO,例如Unix的select和poll。现代操作系统中,线程数已经得到了极大的提升,如NPTL线程软件包可支持数十万的线程。
WindSun
2019/09/09
1.3K0
I/O多路复用select/poll/epoll
IO 多路复用
为了讲多路复用,当然还是要跟风,采用鞭尸的思路,先讲讲传统的网络 IO 的弊端,用拉踩的方式捧起多路复用 IO 的优势。
敖丙
2021/07/27
9770
IO 多路复用
「网络IO套路」当时就靠它追到女友
今天分享的基本上一面试就会被问的网络IO,文中涉及的代码部分不太重要,重要的是对这概念的理解。在看文章之前大家也可通过下面的思维导图看看自己是否能回答出来。
五分钟学算法
2020/09/27
5580
「网络IO套路」当时就靠它追到女友
【网络】五种IO模型&&多路转接select/poll/epoll&&Reactor反应堆模式
如果内核还未将数据准备好,系统调用仍然会直接返回,并且返回 EWOULDBLOCK 错误码
用户10925563
2024/12/22
2030
【网络】五种IO模型&&多路转接select/poll/epoll&&Reactor反应堆模式
select和epoll模型
转自https://www.cnblogs.com/lojunren/p/3856290.html
大学里的混子
2019/03/14
1.1K0
linux 网络编程 I/O复用 select,poll ,epoll
http://blog.csdn.net/zs634134578/article/details/19929449
bear_fish
2018/09/20
2.7K0
linux 下经典 IO 复用模型 -- epoll 的使用
epoll 是 linux 内核为处理大批量文件描述符而对 poll 进行的改进版本,是 linux 下多路复用 IO 接口 select/poll 的增强版本,显著提高了程序在大量并发连接中只有少量活跃的情况下的CPU利用率。 在获取事件时,它无需遍历整个被侦听描述符集,只要遍历被内核 IO 事件异步唤醒而加入 ready 队列的描述符集合就行了。 epoll 除了提供 select/poll 所提供的 IO 事件的电平触发,还提供了边沿触发,,这样做可以使得用户空间程序有可能缓存 IO 状态,减少 epoll_wait 或 epoll_pwait 的调用,提高程序效率。
用户3147702
2022/06/27
7710
linux 下经典 IO 复用模型 -- epoll 的使用
Linux IO多路复用模型
流指的是可以进行I/O操作的内核对象,例如: 文件,管道和套接字等,流的入口就是文件描述符fd。
大忽悠爱学习
2022/09/29
8400
Linux IO多路复用模型
关于I/O与并发
由于笔者在之前发布的一文玩转NGINX中提到过I/O复用模型,在此另起一篇文章简述相关技术。
中龙技术
2022/09/30
6450
关于I/O与并发
【Linux】I/O多路复用-SELECT/POLL/EPOLL
I/O多路复用 前言 文本相关参考资料及部分内容来源 《Linux高性能服务器编程》 《TCP/IP网络编程》 《Linux/UNIX系统编程手册》 ---- I/O多路复用核心思想为,使用一个线程,来处理多个客户端的请求。 或者说,使用一个特殊的fd,监视多个fd。 使得程序能同时监听多个文件描述符,这对提高程序的性能至关重要。 通常,网络程序在下列情况下需要使用I/O多路复用技术。 客户端程序需要同时处理多个socket。 客户端程序要同时处理用户输入和网络连接。 TCP服务器要同
半生瓜的blog
2023/05/13
1.1K0
【Linux】I/O多路复用-SELECT/POLL/EPOLL
Netty如何做到单机百万并发?
今天给大家分享一篇万字长文《微言 Netty:百万并发基石上的 epoll 之剑》。
肉眼品世界
2021/06/08
9700
彻底理解 IO多路复用
https://github.com/caijinlin/learning-pratice/tree/master/linux/io
范蠡
2020/08/18
1.5K0
epoll,求知者离我近点
上网一搜epoll,基本是这样的结果出来:《多路转接I/O – epoll模型》,万变不离这个标题。 但是呢,不变的事物,我们就更应该抓出其中的重点了。 多路、转接、I/O、模型。 别急,先记住这几个词,我比较喜欢你们看我文章的时候带着问题。
看、未来
2020/08/25
5450
epoll,求知者离我近点
一文读懂 Linux 网络 IO 模型
C 是 Client 单词首字母缩写,10K 指 1 万,C10K 指单机同时处理 1 万个并发连接问题。
恋喵大鲤鱼
2023/11/22
4800
一文读懂 Linux 网络 IO 模型
面试系列之-Redis高性能io模型
传统的IO模型了处理一个Get请求,需要监听客户端请求(bind/listen),和客户端建立连接(accept),从 socket中读取请求(recv),解析客户端发送请求(parse),根据请求类型读取键值数据(get),最后给客户端返回结果即向 socket中写回数据(send);
用户4283147
2023/08/21
3980
面试系列之-Redis高性能io模型
一文读懂Redis中的多路复用模型
首先,Redis 是跑在单线程中的,所有的操作都是按照顺序线性执行的,但是由于读写操作等待用户输入或输出都是阻塞的,所以 I/O 操作在一般情况下往往不能直接返回,这会导致某一文件的 I/O 阻塞导致整个进程无法对其它客户提供服务,而 I/O 多路复用就是为了解决这个问题而出现的。
用户2781897
2021/04/02
1K0
epoll使用详解
 Linux平台上传统的I/O复用模型有select和poll模型,但二者在解决大量并发请示时却表现不佳。与select/poll相比,epoll的优点体现在以下三个方面:
王亚昌
2018/08/03
3.7K2
Linux内核编程--常见IO模型与select/poll/epoll编程
套接字上的数据传输分两步执行:第一步,等待网络中的数据送达,将送达后的数据复制到内核中的缓冲区。第二步,把数据从内核中的缓冲区拷贝到应用进程的缓冲区。整个过程的运行空间是从应用进程空间切换到内核进程空间然后再切换回应用进程空间。
Coder-ZZ
2022/06/23
1.5K0
Linux内核编程--常见IO模型与select/poll/epoll编程
一文搞懂select、poll和epoll区别
select本质上是通过设置或检查存放fd标志位的数据结构进行下一步处理。 这带来缺点:
JavaEdge
2021/02/23
3.8K0
一文搞懂select、poll和epoll区别
深入剖析Linux网络设计中网络IO的重要角色
网络编程主要关注四个问题:连接的建立、断开连接、消息到达、消息发送。 不管使用什么样的网络模型,不管使用的是阻塞IO还是非阻塞IO,不管是同步IO还是异步IO,都需要关注这四个问题。
Lion 莱恩呀
2024/08/17
2580
深入剖析Linux网络设计中网络IO的重要角色
相关推荐
I/O多路复用select/poll/epoll
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验