MEF 编程指南(六):导出和元数据
声明导出解释了部件导出服务的基础知识和价值观(Values)。有时候出于种种原因,导出关联信息是非常必要的。通常,用于解释关于功能公共契约的具体实现。允许导入满足约束要求的导出,或者导入所有可用的实现并且在导出前在运行时检查他们的功能。
[Export(typeof(IMessageSender))]
[ExportMetadata("transport", "smtp")]
public class EmailSender : IMessageSender
{
public void Send(string message)
{
Console.WriteLine(message);
}
} [Export(typeof(IMessageSender))]
[ExportMetadata("transport", "smtp")]
[ExportMetadata("secure", null)]
public class SecureEmailSender : IMessageSender
{
public void Send(string message)
{
Console.WriteLine(message);
}
} [Export(typeof(IMessageSender))]
[ExportMetadata("transport", "phone_network")]
public class SMSSender : IMessageSender
{
public void Send(string message)
{
Console.WriteLine(message);
}
} public interface IMessageSender
{
void Send(string message);
}
[MetadataAttribute]
[AttributeUsage(AttributeTargets.Class, AllowMultiple=false)]
public class MessageSenderAttribute : ExportAttribute
{
public MessageSenderAttribute() : base(typeof(IMessageSender)) { }
public MessageTransport Transport { get; set; }
public bool IsSecure { get; set; }
} public enum MessageTransport
{
Undefined,
Smtp,
PhoneNetwork,
Other
} public interface IMessageSender
{
void Send(string message);
}
[MessageSender(Transport=MessageTransport.Smtp)]
public class EmailSender : IMessageSender
{
public void Send(string message)
{
Console.WriteLine(message);
}
} [MessageSender(Transport=MessageTransport.Smtp, IsSecure=true)]
public class SecureEmailSender : IMessageSender
{
public void Send(string message)
{
Console.WriteLine(message);
}
} [MessageSender(Transport=MessageTransport.PhoneNetwork)]
public class SMSSender : IMessageSender
{
public void Send(string message)
{
Console.WriteLine(message);
}
}
public interface IMessageSenderCapabilities
{
MessageTransport Transport { get; }
bool IsSecure { get; }
}
public class HttpServerHealthMonitor
{
[ImportMany]
public Lazy<IMessageSender, IMessageSenderCapabilities>[] Senders { get; set; } public void SendNotification()
{
Compose();
foreach (var sender in Senders)
{
if (sender.Metadata.Transport == MessageTransport.Smtp && sender.Metadata.IsSecure)
{
var messageSender = sender.Value;
messageSender.Send("Server is fine"); break;
}
}
} private void Compose()
{
//var container = new CompositionContainer();
//container.ComposeParts(this, new EmailSender());
AssemblyCatalog catalog = new AssemblyCatalog(Assembly.GetExecutingAssembly());
var container = new CompositionContainer(catalog);
container.ComposeParts(this);
}
}
public class HttpServerHealthMonitor
{
[ImportMany]
public Lazy<IMessageSender, IDictionary<string, object>>[] Senders { get; set; } public void SendNotification()
{
Compose(); foreach (var sender in Senders)
{
if (sender.Metadata.ContainsKey("Transport"))
{
var messageSender = sender.Value;
messageSender.Send("Server is fine");
}
}
} private void Compose()
{
//var container = new CompositionContainer();
//container.ComposeParts(this, new EmailSender());
AssemblyCatalog catalog = new AssemblyCatalog(Assembly.GetExecutingAssembly());
var container = new CompositionContainer(catalog);
container.ComposeParts(this);
}
}
public interface IMessageSenderCapabilities
{
MessageTransport Transport { get; }
[DefaultValue(false)]
bool IsSecure { get; }
}
MEF 编程指南(六):导出和元数据的更多相关文章
- MEF 编程指南(二):定义可组合部件和契约
可组合部件(Composable Parts) 在 MEF 内部可组合部件是一个可组合单元.可组合部件导出其他可组合部件需要的服务,并且从其他可组合部件导入服务.在 MEF 编程模型中,可组合部件 ...
- MEF 编程指南(九):部件生命周期
理解 MEF 容器部件生命周期和实现是非常重要的事情.考虑到 MEF 关注可扩展应用程序.这变得尤为重要.生命期可以解释为期望部件的共享性(transitively, its exports) 共 ...
- MEF 编程指南(五):延迟导出
在组合部件的时候,导入将会触发部件(部件集合)的实例化,为原始的请求部件公开必要的导出需求.对于有些应用程序,推迟实例化 - 并且防止递归组合图(Recursive Composition Down ...
- MEF 编程指南(三):声明导出
组合部件通过 [System.ComponentModel.Composition.ExportAttribute] 特性声明导出.MEF 有几种不同的方式声明导出,包括在部件层面(Part Leve ...
- MEF 编程指南(七):使用目录
目录(Catalogs) MEF 特性编程模型的核心价值,拥有通过目录动态地发现部件的能力.目录允许应用程序轻松地使用那些通过 Export Attribute 注册自身的导出.下面列出 MEF ...
- MEF 编程指南(十二):批量组合
MEF 容器实例并非不可变的.如果目录支持改变(像监控目录变动)或者在运行时添加/移除部件都可能发生改变.以前,你不得不做出改动并且调用 CompositionContainer 上的 Compose ...
- MEF 编程指南(十一):查询 CompositionContainer
CompositionContainer 公开了一部分获取导出.导出对象以及两者集合的重载. 在这些方法重载中,你应该遵循下面的共享行为准则 - 除非特别说明. 当请求单一实例的时候,如果没发 ...
- MEF 编程指南(八):过滤目录
当使用子容器的时候,基于特定的标准(Specific Criteria)过滤目录是很必要的.比如,基于部件构造策略的过滤器是很常见的.下面的代码片段演示了如何构建的特殊途径(Particular Ap ...
- MEF 编程指南(四):声明导入
组合部件通过 [System.ComponentModel.Composition.ImportAttribute] 特性声明导入.类似于导出,也有几种不同的方法声明导入,即通过:字段(Fields) ...
随机推荐
- POJ 2942 Knights of the Round Table (点双连通分量)
题意:多个骑士要开会,3人及以上才能凑一桌,其中部分人已经互相讨厌,肯定不坐在同一桌的相邻位置,而且一桌只能奇数个人才能开台.给出多个人的互相讨厌图,要求多少人开不成会(注:会议不要求同时进行,一个人 ...
- group by的使用
1.概述 2.原始表 3.简单Group By 4.Group By 和 Order By 5.Group By中Select指定的字段限制 6.Group By All 7.Group By与聚合函 ...
- HTTP请求中浏览器的缓存机制
摘要:在Web开发过程中,我们可能会经常遇到浏览器缓存的问题.本文作者详细解释了浏览器缓存的机制,帮助读者更深层次的认识浏览器的缓存. 流程 当资源第一次被访问的时候,HTTP头部如下 (Reques ...
- C#中的lock关键字
前几天与同事激烈讨论了一下,有一点收获,记录起来. 首先给出MSDN的定义: lock 关键字可以用来确保代码块完成运行,而不会被其他线程中断.这是通过在代码块运行期间为给定对象获取互斥锁来实现的. ...
- python 去掉\n\t多余空格
>>> import re >>> sss = "SELECT a.id,\n a.customer_id as user_id,\n ...
- ASP.NET CS文件中输出JavaScript脚本的3种方法以及区别
Response.Write 与 Page.ClientScript.RegisterStartupScript 与 Page.ClientScript.RegisterClientScriptB ...
- 3D 矩阵旋转
如图,需要将点(向量) v(x, y, 0) 绕 z 轴旋转角度 θ,求旋转后的点(向量) v'(x', y', 0). 大概思路: 1. 将 v(x, y, 0) 分解, v(x, y, 0) = ...
- webpack入门级教程
Webpack是什么 首先可以看下官方文档,文档是最好的老师. 这里也有国外的一个朋友写的入门介绍. Webpack是由Tobias Koppers开发的一个开源前端模块构建工具.它的基本功能是将以模 ...
- 为什么你写的Python运行的那么慢呢?
大约在一年前,也就是2013年在Waza(地名),Alex Gaynor提到了一个很好的话题:为什么用Python.Ruby和Javascript写的程序总是运行的很慢呢?正如他强调的,关键就是现在出 ...
- http响应Last-Modified和ETag(转)
基础知识 1) 什么是”Last-Modified”? 在浏览器第一次请求某一个URL时,服务器端的返回状态会是200,内容是你请求的资源,同时有一个Last-Modified的属性标记此文件在服务期 ...