实战MEF(3):只导出类的成员

本文我同时发布在另一个博客:http://www.cnblogs.com/tcjiaan/p/3288861.html

 

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

}

}

}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Managed Extensibility Framework(MEF)是 .NET Framework 和 .NET Core 中的一个插件化框架,可以帮助开发者实现可扩展的应用程序。MEF 框架在 .NET Core 中是自带的,不需要额外安装。 使用 MEF 框架实现插件化开发的步骤如下: 1. 创建插件接口 首先需要定义一个插件接口,该接口定义了插件的基本功能和方法。例如: ```csharp public interface IPlugin { string Name { get; } void Execute(); } ``` 2. 创建插件实现 接着需要创建一个或多个实现插件接口的。例如: ```csharp [Export(typeof(IPlugin))] public class Plugin1 : IPlugin { public string Name => "Plugin1"; public void Execute() { Console.WriteLine("Plugin1 executed."); } } [Export(typeof(IPlugin))] public class Plugin2 : IPlugin { public string Name => "Plugin2"; public void Execute() { Console.WriteLine("Plugin2 executed."); } } ``` 注意:实现需要使用 `[Export]` 属性进行标记,表示该是一个插件。 3. 创建主程序 创建主程序并使用 MEF 框架加载插件。例如: ```csharp class Program { static void Main(string[] args) { var catalog = new DirectoryCatalog("plugins"); // 插件目录 var container = new CompositionContainer(catalog); foreach (var plugin in container.GetExportedValues<IPlugin>()) { Console.WriteLine("Loaded plugin: " + plugin.Name); plugin.Execute(); } } } ``` 这段代码会从指定的插件目录中加载所有插件,并执行 `Execute` 方法。 注意:需要在主程序中添加对 `System.ComponentModel.Composition` 命名空间的引用,才能使用 MEF 相关的。 这就是使用 MEF 框架实现插件化开发的基本步骤。在实际应用中,可以根据具体的需求进行更加复杂的插件实现。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值