通过前面两篇文章的介绍,相信各位会明白MEF中有不少实用价值。上一文中我们也讨论了导入与导出,对于导出导入,今天我们再深入一点点,嗯,只是深入一点点而已,不会很难的,请大家务必放心,如果大家觉得看文章枯燥,不妨一边喝牛奶一边阅读。

上一文中我们都是把整个类型(整个类)进行导出,不过有时候,我们可能会考虑只导出类的某些成员,比如某个属性或某个字段等。

我们还是少说理论,免得大家喝不下牛奶,还是直接上菜吧。为了便于测试,以下示例把组件都写在当前程序集中,也就是在同一个项目,然后用AssemblyCatalog来查找。

首先,定义一个公共接口IWork。

然后分别用两个类来实现该接口。

接着,我们再定义一个总类,包含两个属性,分别返回FirstWork类和SecondWork类的实例。

ExportAttribute特性只附加在WorkFirst和WorkSecond两个属性上,Works类只导出这两个属性。

随后,我们组装并调用这些导出部件。

然后我们运行一下示例,就可以得到如下图所示的结果:

很多人学习编程很喜欢直接Ctrl + C别人的代码,这是一种相当不好的学习方法,所以我把代码都弄成截图了,哈哈。

我事前在导入字段声明时用了Lazy<T>,但发现不能创建对象,可能的原因是我们导出的是类的一部分,内部运行时在组装部件时需要Works类进行实例化,因为如果Works对象不实例化的话,就导不出WorkFirst和WorkSecond属性了。也许是这个原因导致的吧。

这时候大家可能会想,如果我在Works类中定义一个方法,我想导出这个方法怎么办?

既然想到了还等什么,马上试试就知道了,我们把Works类的代码改一下,导出一个ViewWork方法。

协定类型为什么使用Func<TResult>呢?为什么,大家好好思考一下,用什么方式来表示方法的签名与形式最形象?想想吧。

接着我们在Program类中导入这个方法。

导入的协定名与协定类型一定要与导出匹配,否则无法导入。这就好比你的言行要匹配一样,否则妹子不会理你。

在完成组装的代码后面,我们测试调用导入的方法。

然后运行一下,看看有没有结果。

不过,最后,还是把完整的代码贴一下。

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

using System.ComponentModel.Composition;

using System.ComponentModel.Composition.Hosting;

using System.Reflection;

namespace MefApp

{

// 作为公共接口

public interface IWork

{

void DoSome();

string WName { get; }

}

// 第一个实现公共接口的类

public class FirstWork : IWork

{

public void DoSome()

{

Console.WriteLine("工序一执行。");

}

public string WName

{

get { return "工序一"; }

}

}

// 第二个实现公共接口的类

public class SecondWork : IWork

{

public void DoSome()

{

Console.WriteLine("工序二执行。");

}

public string WName

{

get { return "工序二"; }

}

}

// 只对成员进行导出的类

public class Works

{

FirstWork fw;

SecondWork sw;

public Works()

{

// 初始化

fw = new FirstWork();

sw = new SecondWork();

}

// 该属性被导出

[Export("work 1", typeof(IWork))]

public IWork WorkFirst { get {

return fw;

} }

// 该属性被导出

[Export("work 2", typeof(IWork))]

public IWork WorkSecond

{

get { return sw; }

}

// 导出方法

[Export("view work", typeof(Func<string>))]

public string ViewWork()

{

return "本生产线国际一流,由3172个工作单元组成,73265道工序。";

}

}

class Program

{

// 导入

[Import("work 1", typeof(IWork))]

public IWork TheImportFirstWork;

// 导入

[Import("work 2", typeof(IWork))]

public IWork TheImportSecondWork;

// 导入

[Import("view work", typeof(Func<string>))]

public Func<string> TheImportViewWorkMethod;

static void Main(string[] args)

{

// 从当前程序集中发现组件

AssemblyCatalog cat = new AssemblyCatalog(typeof(Program).Assembly);

Program p = new Program();

CompositionContainer container = new CompositionContainer(cat);

container.SatisfyImportsOnce(p);//给合

// 调用测试

if (p.TheImportFirstWork!=null)

{

Console.Write("类型名:{0} Name:{1} 调用结果:",

p.TheImportFirstWork.GetType().Name,

p.TheImportFirstWork.WName);

p.TheImportFirstWork.DoSome();

}

if (p.TheImportSecondWork != null)

{

Console.Write("类型名:{0} Name:{1} 调用结果:",

p.TheImportSecondWork.GetType().Name,

p.TheImportSecondWork.WName);

p.TheImportSecondWork.DoSome();

}

if (p.TheImportViewWorkMethod != null)

{

Console.WriteLine(p.TheImportViewWorkMethod());

}

// 释容器以及其创建的实例

container.Dispose();

Console.Read();

}

}

}

转载于:https://www.cnblogs.com/tcjiaan/p/3288861.html

实战MEF(3):只导出类的成员相关推荐

  1. win32以动态链接库导出类及其成员变量

    本文转自:http://hi.baidu.com/ah_leo/blog/item/eccf12f49a0ebce07709d744.html 通常我们在vc程序时候,希望把自己的代码隐藏起来,做成d ...

  2. Qt使用导出类报错:error C2491: “ZMapWidget::staticMetaObject”: 不允许 dllimport 静态数据成员 的定义

    在使用一个继承自QObject带有Q_OBJECT宏的导出类时,编译报错:不允许 dllimport 静态数据成员 的定义. 原因是自动生成的moc文件带有静态函数,无法导出. 1.在Qt中的解决办法 ...

  3. c# MEF框架(三 导出类的方法和属性)

    转自:http://www.cnblogs.com/yunfeifei/p/3927663.html 前面说完了导入和导出的几种方法,如果大家细心的话会注意到前面我们导出的都是类,那么方法和属性能不能 ...

  4. Qt使用导出类报错:error C2491: “LmcThreadPaddle::staticMetaObject”: 不允许 dllimport 静态数据成员 的定义

    Qt使用导出类报错:error C2491: "LmcThreadPaddle::staticMetaObject": 不允许 dllimport 静态数据成员 的定义 在使用继承 ...

  5. Java性能优化(12):最小化类和成员可访问能力

    类和接口是Java程序设计语言的核心,它们也是Java语言的基本抽象单元.Java语言提供了许多强大的基本元素,供程序猿来设计类和接口. 要想区别一个设计良好的模块与一个设计不好的模块,最重要的因素是 ...

  6. Effective Java之使类和成员的可访问性最小化(十三)

    对于类 对于类,只有public和package-private两种访问级别. 1.对于顶层的类来说,只有包级私有和公有两种可能,区别是包级私有意味着只能在当前包中使用,不会成为导出api的一部分,而 ...

  7. c#调用C++写的dll导出类,如何实现

    网上看了一些都是调用c++写函数能不能实现c#使用c++写的类各位高手请赐教 解决方案 » 类的有一个成员函数,是返回这个类的指针,那么在C#里面就是一个INTPTR,它是什么你不用管.然后C++文件 ...

  8. dll的概念、dll导出类(转)

    1. DLL的概念 DLL(Dynamic Linkable Library),动态链接库,可以向程序提供一些函数.变量或类.这些可以直接拿来使用. 静态链接库与动态链接库的区别: (1)静态链接库与 ...

  9. 类的成员和嵌套(建模)

    一. 类的成员共分为三类: 字段, 方法, 属性 class Foo:country = '中国' # 静态字段def __init__(self, name):self.name = name # ...

  10. 类的成员包含 java_Java 面向对象(十五)类的成员 之 内部类

    一.内部类 1.引入 类的成员包括: (1)属性:成员变量: (2)方法:成员方法: (3)构造器: (4)代码块: (5)内部类: 其中1.2是代表这类事物的特征: 其中3.4是初始化类和对象用的: ...

最新文章

  1. 离开互联网大厂的年轻人都去了哪儿?
  2. solidwork2019/2020安装后出现无法获得许可证
  3. 【Vegas2006】自我介绍for校青春风采大赛
  4. NHibernate 与Oracle 点滴
  5. 信道检测手机软件 ios_【手机软件】云听:稀有神器,移动音频的国家队,某拉雅资源它都有!...
  6. 给element的select添加复选框
  7. Linux——alias 设置别名详解
  8. 高效实用Kafka-入门介绍
  9. 数据分析写作——程序员的另外一种输出
  10. 谷歌要求华为不启用鸿蒙,谷歌:华为我不让你用我的服务!华为:我还是照样用!...
  11. 程序员不得不了解的硬核知识大全
  12. 【笔记】《算法竞赛 从入门到进阶(罗勇军)》第7章 动态规划
  13. YOLOv4论文中文翻译
  14. Composer 国内镜像大全(可用镜像列表)
  15. Cisco ❀ 数据封装
  16. vue中的vxe-table中文文档
  17. 虹科分享|用于 VMware 的 ATTO vConfigTool™ 插件
  18. CentOS 系统利用 IUS 安装 python3.6
  19. 01UI-day7-160105
  20. 低代码开发平台都有哪些?国内外十几大低代码开发平台——汇总分析

热门文章

  1. STM32通过定时器捕获的方法驱动(HC-SR04)超声波测距模块
  2. 处理数字音乐文件用计算机软件,工具软件商标注册属于第几类?
  3. 香农编码实验报告matlab,实验三 香农编码
  4. springboot批量更新实体_springboot快速集成swagger
  5. java编辑遗忘曲线代码_用jsp写出记忆曲线的表格(用学习新概念英语做例子)
  6. DL_C1_week4_2(build a deep neural network 2)
  7. AWS DeepRacer 参数调优 Amazon SageMaker 和 Amazon RoboMaker
  8. 极客大学产品经理训练营 认识产品经理上 第1课总结
  9. 数据集:波士顿地区房价预测
  10. 2021-09-01175. 组合两个表 SQL