插件问题回答第4题

问题原贴: [url]http://cloverprince.iteye.com/admin/blogs/481307[/url]

[quote]4. 现有一个主程序用C#语言写成。现在要允许第三方开发人员编写扩展的类,约定第三方开发的类必须包含一个实现了某个已知接口(如interface IFooPlugin)的类,名称不限。如果要求第三方的类必须与主程序的二进制代码分开发布,把dll丢在某个文件夹内即可被动态装载使用,应如何实现?
[/quote]

回答:

每个插件作为一个程序集(Assembly),dll的形式。里面包含一个实现已知接口的类。使用Assembly.LoadFile()装载该插件,用Assembly.GetInterface()寻找程序集中实现了已知接口的类,用Activator.CreateInstance创建实例。


适用范围:

Mono2.0和Visual C# 2008中测试通过。反射机制自.NET 1.0开始就有。


实现:

先指定一个接口,比如叫Cloverprince.IPlugin。插件必须包含一个类,实现这个接口。

using System;

namespace Cloverprince
{
public interface IPlugin
{
String Name {get;set;} // 设定和获取名字
void Greet(); // 打招呼
}
}



创建一个插件。插件包含一个类,实现这个接口。
这个类叫HelloWorldPlugin.HelloWorld。

using System;
using Cloverprince;

namespace HelloworldPlugin
{
public class HelloWorld: Cloverprince.IPlugin
{
private String _Name;
public String Name {
get {
return _Name;
}
set {
_Name = value;
}
}
public void Greet() {
Console.WriteLine("Hello, {0}",Name);
}
}
}

这个类将被编译成一个dll程序集


另一个插件也类似的制作。
类名:GoodbyePlugin.GoodbyeWorld:

using System;
using Cloverprince;

namespace GoodbyePlugin
{
public class GoodbyeWorld: Cloverprince.IPlugin
{
public String Name { get;set; }
public void Greet() {
Console.WriteLine("Goodbye, {0}",Name);
}
}
}

编译成另一个dll。


现在,两个插件已经有了,只差一个主程序来读取这两个插件了。
主程序:

using System;
using System.IO;
using System.Reflection;

using Cloverprince;

namespace Main
{
class MainClass
{
private const String PLUGINS_PATH="plugins";
public static void Main(string[] args)
{
foreach(String fileName in Directory.GetFiles(PLUGINS_PATH,"*.dll"))
{
Assembly ass = Assembly.LoadFile(Path.GetFullPath(fileName));
foreach(Type t in ass.GetTypes()) {
if(t.GetInterface("Cloverprince.IPlugin") != null) {
IPlugin p = (IPlugin)Activator.CreateInstance(t);
p.Name="Cloverprince";
p.Greet();
}
}
}
}
}
}


以上,所有需要的文件齐备。


编译:

如上所述,每个插件编译成一个dll程序集,主程序随意。注意路径。


执行:

执行该程序需要的最小文件集(3个文件):
[quote].
|-- Main.exe
`-- plugins
|-- GoodbyeWorld.dll
`-- HelloworldPlugin.dll
[/quote]


执行:
Windows: Main 或者直接双击图标
Unix+Mono: mono Main.exe

[quote]Goodbye, Cloverprince
Hello, Cloverprince
[/quote]


总结:
1. 主程序并不了解plugins目录中有多少插件。在运行时列举目录。
2. 主程序对每个plugins文件(比如叫HelloworldPlugin.dll)的了解只有:
- 这个程序集中有0个或多个类实现了IPlugin接口。
- 这个类拥有一个不带参数的构造方法。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值