实战MEF(3):只导出类的成员
通过前面两篇文章的介绍,相信各位会明白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):只导出类的成员的更多相关文章
- MEF只导出类的成员
MEF只导出类的成员 通过前面两篇文章的介绍,相信各位会明白MEF中有不少实用价值.上一文中我们也讨论了导入与导出,对于导出导入,今天我们再深入一点点,嗯,只是深入一点点而已,不会很难的,请大家务必放 ...
- 实战MEF(2):导出&导入
上一文中,我们大致明白了,利用MEF框架实现自动扫描并组装扩展组件的思路.本文我们继续前进,从最初的定义公共接口开始,一步步学会如何使用MEF. 在上一文中我们知道,对于每一个实现了公共规范的扩展组件 ...
- C#可扩展编程之MEF学习笔记(三):导出类的方法和属性
前面说完了导入和导出的几种方法,如果大家细心的话会注意到前面我们导出的都是类,那么方法和属性能不能导出呢???答案是肯定的,下面就来说下MEF是如何导出方法和属性的. 还是前面的代码,第二篇中已经提供 ...
- C#可扩展编程之MEF(三):导出类的方法和属性
前面说完了导入和导出的几种方法,如果大家细心的话会注意到前面我们导出的都是类,那么方法和属性能不能导出呢???答案是肯定的,下面就来说下MEF是如何导出方法和属性的. 还是前面的代码,第二篇中已经 ...
- VC++导入导出类
一.导出类 VC++中导出类很简单,下面列出了两个等价的方法: 方法1: class __declspec(dllexport) CTest { public: int m_nValue ...
- Effective Java 第三版——15. 使类和成员的可访问性最小化
Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...
- DLL导出类避免地狱问题的完美解决方案
DLL动态链接库是程序复用的重要方式,DLL可以导出函数,使函数被多个程序复用,DLL中的函数实现可以被修改而无需重新编译和连接使用该DLL的应用程序.作为一名面向对象的程序员,希望DLL可以导出类, ...
- (转)C++类库开发之导出类设计原则
上一篇博客详细陈述了类库开发的各个知识点(http://blog.csdn.net/z702143700/article/details/45989993),本文将进一步陈述,对于类库开发过程中导出类 ...
- EffectiveJava(13)使类和成员的可访问性最小化
1.为什么要使类和成员可访问性最小化 它可以有效地解除组成系统的各模块之间的耦合关系,使得这些模块可以独立的开发 测试 优化 使用 理解和修改.提高软件的可重用性 2.成员的访问级别 私有(priva ...
随机推荐
- VS2015 RTM与ASP.NET 5 RC1之坑
最近Asp.Net 5的RC1出来了 VS2015的Update1也开始进入RC阶段 嗯,微软尿性,是时候转移到VS2015了 开始踩坑之旅 装好VS2015后,当然是开始折腾ASP.Net 5嘛 建 ...
- 20161023 NOIP 模拟赛 T1 解题报告
Task 1.纸盒子 (box.pas/box.c/box.cpp) [题目描述] Mcx是一个有轻度洁癖的小朋友.有一天,当他沉溺于数学卷子难以自拔的时候,恍惚间想起在自己当初学习概率的时候准备的一 ...
- C++中const的全面总结
C++中的const关键字的用法非常灵活,而使用const将大大改善程序的健壮性,本人根据各方面查到的资料进行总结如下,期望对朋友们有所帮助. Const 是C++中常用的类型修饰符,常类型是指使用类 ...
- 《JavaScript高级程序设计(第3版)》阅读总结记录第一章之JavaScript简介
前言: 为什么会想到把<JavaScript 高级程序设计(第 3 版)>总结记录呢,之前写过一篇博客,研究的轮播效果,后来又去看了<JavaScript 高级程序设计(第3版)&g ...
- 一眼看懂深浅拷贝(clone)-C#
这是使用的是序列化的方式实现深拷贝 [Serializable] class Person:ICloneable { /// <summary> /// 字符串在clone 中类似于值类型 ...
- Javascript初学篇章_6(BOM)
BOM 浏览器对象模型 BOM (浏览器对象模型),它提供了与浏览器窗口进行交互的对象 一.window对象 Window对 象表示整个浏览器窗口. 1.系统消息框 alert() alert('he ...
- Django 搭建简易博客
新增一个 APP 博客算是一个功能集,因此我们应将其体现为一个模块.这表现在 Django 应用里则是为其创建一个 APP Package.现在让 manage.py 中的 startapp 闪亮登场 ...
- linux进程管理(上)
程序和进程的区别: 1.程序是一种静态资源 程序启动产生进程 2.程序与进程无一一对应原则 进程是动态的一个过程 父进程和子进程在前面提过 前台进程:执行命令时只能等待的进程为前台进程也叫异步进程 ...
- C# WinForm 导出导入Excel/Doc 完整实例教程[使用Aspose.Cells.dll]
[csharp] view plain copy 1.添加引用: Aspose.Cells.dll(我们就叫工具包吧,可以从网上下载.关于它的操作我在“Aspose.Cells操作说明 中文版 下载 ...
- 关于shiro
1.1 简介 Apache Shiro是Java的一个安全框架.目前,使用Apache Shiro的人越来越多,因为它相当简单,对比Spring Security,可能没有Spring Securi ...