出口和元数据

声明出口解释基本的部件输出服务和值。有些情况由于种种原因需要用出口关联信息。一般情况下它是用来解释一个公共契约具体实现的性能。这可以有效地满足允许出口或者限制出口,或者在那时导入所有可用的实现和在使用出口之前检查它们的运行能力。

附加元数据到出口

想一下我们之前的IMessageSender服务。假如我们有一些实现,而这些实现与消者有关而有所不同。在我们的例子里消息是否运行和是否安全对消费者(importer)是重要的信息。

使用ExportMetadataAttribute

附加这些信息我们只需要做的就是使用[System.ComponentModel.Composition.ExportMetadataAttribute]:

public interface IMessageSender
{void Send(string message);
}[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);}
}

使用自定义出口属性

为了使它比ExportMetadataAttribute更严格的类型,你需要创建自己的属性并且用[System.ComponentModel.Composition.MetadataAttribute]修饰.在这个例子里面,我们也从ExportAttribute派生,所以创建一个自定义出口属性也是指定的元数据。

[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
}

上面的例子里,MetadataAttribute应用于自定义的出口属性,下一步是应用属性到IMessageSender实现。

[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);}
}

这就是出口方所必须的。在引擎里,MEF仍作为一个字典,但这个事实对你来说是无形的。

注意:你也可以创建元数据属性不是他们自己出口,只需要通过创建使用MetadataAttributeAttribute修饰的属性。

在这些例子里元数据会被添加到出口自定义元数据属性被应用的同一成员里。

进口元数据

进口商可以访问附加到出口的元数据。

使用强类型元数据

若要以强类型的方式访问元数据通过定义接口匹配只读属性 (名称和类型)来创建元数据视图。 对于我们的示例来说将是类似于以下内容一个接口:

public interface IMessageSenderCapabilities
{MessageTransport Transport { get; }bool IsSecure { get; }
}

于是你可以开始用System.Lazy<T, TMetadata>导入。(T是契约类型,TMetadata是你创建的接口)

[Export]
public class HttpServerHealthMonitor
{[ImportMany]public Lazy<IMessageSender, IMessageSenderCapabilities>[] Senders { get; set; }public void SendNotification(){foreach(var sender in Senders){if (sender.Metadata.Transport == MessageTransport.Smtp && sender.Metadata.IsSecure){var messageSender = sender.Value;messageSender.Send("Server is fine");break;}}}
}

使用弱类型元数据
为了以弱类型方式访问元数据,你使用System.Lazy<T, TMetadata>类型进口传递IDictionary<string,object>元数据。然后你就可以通过作为字典的元数据属性来访问元数据。

注意:一般我们推荐用强类型方法去访问元数据,然而有些系统需要通过动态方式访问元数据,这也是允许的。

[Export]
public class HttpServerHealthMonitor
{[ImportMany]public Lazy<IMessageSender, IDictionary<string,object>>[] Senders { get; set; }public void SendNotification(){foreach(var sender in Senders){if (sender.Metadata.ContainsKey("Transport") && sender.Metadata["Transport"] == MessageTransport.Smtp && sender.Metadata.ContainsKey("Issecure") && Metadata["IsSecure"] == true){var messageSender = sender.Value;messageSender.Send("Server is fine");break;}}}
}

元数据过滤和默认属性值

当你选中一个元数据视图,一个隐藏的过滤会触发去匹配那些包含在视图定义的元数据属性的出口。你可以在元数据视图里通过System.ComponentModel.DefaultValueAttribute指定属性不需要。在下面你可以看到,我们已经给IsSecure指定一个默认值false。这意味着一个部件出口IMessageSender,但没有提供IsSecure元数据,但它仍然匹配。

public interface IMessageSenderCapabilities
{MessageTransport Transport { get; }[DefaultValue(false)];bool IsSecure { get; }
}

转载于:https://www.cnblogs.com/wangchunming/archive/2012/05/09/2491094.html

MEF学习笔记(6):出口和元数据相关推荐

  1. C#可扩展编程之MEF学习笔记(四):见证奇迹的时刻

    前面三篇讲了MEF的基础和基本到导入导出方法,下面就是见证MEF真正魅力所在的时刻.如果没有看过前面的文章,请到我的博客首页查看. 前面我们都是在一个项目中写了一个类来测试的,但实际开发中,我们往往要 ...

  2. MEF学习笔记(1)——什么是MEF?

    (英文原文:http://mef.codeplex.com/wikipage?title=Overview&referringTitle=Home) 什么是MEF? Managed Exten ...

  3. 元数据管理工具Atlas学习笔记之集成

    文章目录 背景 环境 Atlas安装 solr Atlas Atlas启动 启动Hadoop.ZooKeeper.HBase.Kafka.Hive和MySQL Hadoop 启动ZooKeeper 启 ...

  4. 元数据管理工具Atlas学习笔记之使用

    文章目录 背景 导入元数据 查看元数据 按类型搜索 Hive元数据增量同步 遇到的问题及解决方法 结语 背景 Atlas主要负责同步各服务(主要是Hive)的元数据,并构建元数据实体之间的关联关系,并 ...

  5. 《Angular4从入门到实战》学习笔记

    <Angular4从入门到实战>学习笔记 腾讯课堂:米斯特吴 视频讲座 二〇一九年二月十三日星期三14时14分 What Is Angular?(简介) 前端最流行的主流JavaScrip ...

  6. KALI LINUX渗透测试学习笔记

    KALI LINUX渗透测试学习笔记 (苑房弘主讲) 第1章 课程介绍 任务1:Kali Linux渗透测试介绍.exe 安全问题的根源: 分层思想 只求功能实现 最大的威胁是人 渗透测试: 尝试挫败 ...

  7. 《Angular4从入门到实战》学习笔记(图文)

    <Angular4从入门到实战>学习笔记 腾讯课堂:米斯特吴 视频讲座 二〇一九年二月十三日星期三14时14分 What Is Angular?(简介) 前端最流行的主流JavaScrip ...

  8. deepstream学习笔记(三):deepstream-imagedata-multistream解析与接入适配yolov5模型测试

    引言 上一节重点介绍了gstreamer架构图与各部分组成原理说明,并且针对deepstream-test1介绍了它的整体功能和画出了管道图,本篇博文将详细介绍deepstream-imagedata ...

  9. JVM学习笔记汇总:结合尚硅谷宋红康老师视频教程及PPT

    JVM学习笔记汇总:结合尚硅谷宋红康老师视频教程及PPT 第一章:JVM虚拟机的介绍 1.1虚拟机的分类 虚拟机通常分为两类:系统虚拟机和程序虚机.其中,系统虚拟机是指完全对物理计算机的仿真,而程序虚 ...

最新文章

  1. hive的变量传递设置
  2. java添加信任_ssl-在Java中使用自定义信任库以及默认的on
  3. 从零开始学习python:demo2.3
  4. DFT 与 ATPG综 述
  5. “基因编辑婴儿”惹争议,那你知道机器学习在脱靶效应中的作用吗?
  6. CSS 动画指南: 原理和实战 (一)
  7. 视频解码测试软件,视频解码:视频解码性能测试_平板电脑评测-中关村在线
  8. 手把手教你做线性回归分析,实用且通俗易懂!
  9. 计算机输入法无法输入小写字母,电脑打不出小写字母了怎么办
  10. 禁止使用搜狗浏览器打开QQ邮箱,更换成其他邮箱
  11. iOS组件化:从零开始搭设私有库
  12. ELK——ElasticStack日志分析平台
  13. 【P4论文分享】基于P4的可编程数据平面研究及其应用
  14. Octotree Chrome安装与使用方法
  15. 阿里云 远程桌面 登录
  16. Pytorch安装(Anaconda配置虚拟环境)(cpu版)
  17. 一文入门Go静态单赋值(SSA)
  18. ElasticSearch学习笔记-ngram、中文拼音、简繁体搜索记录
  19. 门禁系统如何规避人脸识别数据使用风险?
  20. 信号的互相关函数由傅里叶变换形式表达以及推导

热门文章

  1. UML 中各种图形重要性的排行
  2. 虽然有索引,但没有用上
  3. SSI 社会信号识别 —— 实时分析和识别人类行为
  4. cocos2dx游戏--欢欢英雄传说--添加游戏背景
  5. iOS开发小技巧--高斯模糊框架的应用
  6. 有关Linux下request.getRealPath(/)获取路径的问题
  7. Latex应用和资源
  8. 设备选购需要注意的几个方面
  9. [MongoDB]db.serverStatus()命令详解
  10. 解决SurfaceView渲染的各种疑难杂症