通过前面两篇文章的介绍,相信各位会明白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();

}

}

}

实战MEF(3):只导出类的成员的更多相关文章

  1. MEF只导出类的成员

    MEF只导出类的成员 通过前面两篇文章的介绍,相信各位会明白MEF中有不少实用价值.上一文中我们也讨论了导入与导出,对于导出导入,今天我们再深入一点点,嗯,只是深入一点点而已,不会很难的,请大家务必放 ...

  2. 实战MEF(2):导出&导入

    上一文中,我们大致明白了,利用MEF框架实现自动扫描并组装扩展组件的思路.本文我们继续前进,从最初的定义公共接口开始,一步步学会如何使用MEF. 在上一文中我们知道,对于每一个实现了公共规范的扩展组件 ...

  3. C#可扩展编程之MEF学习笔记(三):导出类的方法和属性

    前面说完了导入和导出的几种方法,如果大家细心的话会注意到前面我们导出的都是类,那么方法和属性能不能导出呢???答案是肯定的,下面就来说下MEF是如何导出方法和属性的. 还是前面的代码,第二篇中已经提供 ...

  4. C#可扩展编程之MEF(三):导出类的方法和属性

      前面说完了导入和导出的几种方法,如果大家细心的话会注意到前面我们导出的都是类,那么方法和属性能不能导出呢???答案是肯定的,下面就来说下MEF是如何导出方法和属性的. 还是前面的代码,第二篇中已经 ...

  5. VC++导入导出类

    一.导出类 VC++中导出类很简单,下面列出了两个等价的方法: 方法1: class __declspec(dllexport) CTest { public: int        m_nValue ...

  6. Effective Java 第三版——15. 使类和成员的可访问性最小化

    Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...

  7. DLL导出类避免地狱问题的完美解决方案

    DLL动态链接库是程序复用的重要方式,DLL可以导出函数,使函数被多个程序复用,DLL中的函数实现可以被修改而无需重新编译和连接使用该DLL的应用程序.作为一名面向对象的程序员,希望DLL可以导出类, ...

  8. (转)C++类库开发之导出类设计原则

    上一篇博客详细陈述了类库开发的各个知识点(http://blog.csdn.net/z702143700/article/details/45989993),本文将进一步陈述,对于类库开发过程中导出类 ...

  9. EffectiveJava(13)使类和成员的可访问性最小化

    1.为什么要使类和成员可访问性最小化 它可以有效地解除组成系统的各模块之间的耦合关系,使得这些模块可以独立的开发 测试 优化 使用 理解和修改.提高软件的可重用性 2.成员的访问级别 私有(priva ...

随机推荐

  1. 2.1 -1.0 Xcode(发布时间、使用、快捷键、插件相关)

    本文并非最终版本,如有更新或更正会第一时间置顶,联系方式详见文末 如果觉得本文内容过长,请前往本人 “简书” 1.0 Xcode 发布时间 版本 iOS 版本 手机 日期 特殊介绍 Xcode 3.1 ...

  2. 【BZOJ2073】[POI2004]PRZ 状压DP

    [BZOJ2073][POI2004]PRZ Description 一只队伍在爬山时碰到了雪崩,他们在逃跑时遇到了一座桥,他们要尽快的过桥. 桥已经很旧了, 所以它不能承受太重的东西. 任何时候队伍 ...

  3. Redis 主从配置

    环境     Master/Slave     系统 IP Redis版本 Master     CentOS6.7         10.10.3.211         redis-3.2.6   ...

  4. linux shell输出带颜色文本

    echo -e "\033[33;31m Color Text" - red echo -e "\033[33;32m Color Text" - green ...

  5. 安装WAMP 及 修改MYSQL用户名 、 密码

    1,下载并安装WAMP 2,启动服务后,找到MYSQL--MYSQL console--弹出命令窗口(刚开始没有初始用户名跟密码,可直接回车执行) 3,首先输入 use mysq;l---然后修改用户 ...

  6. 命令行操作svn和git和git

    前几天在写代码的时候电脑突然坏掉,老大交代的任务没完成,非常痛恨自己用svn或者git保存代码,相信很多程序员遇到过,硬盘坏掉,存在硬盘中的代码丢失,无法找回的问题,svn和git可谓程序员界的福音, ...

  7. Python之路Day14--html

    本节内容: 一.HTML 二.CSS 三.JS HTML 1.一套规则,浏览器认识的规则. 2.开发者: 学习Html规则 开发后台程序: - 写Html文件(充当模板的作用) ****** - 数据 ...

  8. python方法中的self

    前几天在写一个c作业时,突发奇想,在结构体中加入函数指针, 像这样: struct People { int _age; int (*age)(); }people; 这样调用时就可以 people. ...

  9. MySQL Can't connect to MySQL server on 'localhost' (10061)

    run > services.msc > rightclick MySQL > properties >start 搞定

  10. 【转】成为Java顶尖程序员 ,看这10本书就够了

    “学习的最好途径就是看书“,这是我自己学习并且小有了一定的积累之后的第一体会.个人认为看书有两点好处: 1.能出版出来的书一定是经过反复的思考.雕琢和审核的,因此从专业性的角度来说,一本好书的价值远超 ...