不管你采用什么方式实现插件式的应用程序框架,核心还是动态加载,换句话说,没有动态加载技术也就无所谓插件式的应用程序框架了。使用
Com
实现的话,你可以利用
Com
的
API
通过
ProgID
来动态创建
COM
对象,如果使用普通
DLL
,你需要使用
Windows
的
API
函数
LoadLibrary
来动态加载
DLL
,并用
GetProcAddress
函数来获取函数的地址。而使用
.NET
技术的话,你需要使用
Assembly
类的几个静态的
Load
(
Load
,
LoadFile
,
LoadFrom
)方法来动态加载汇集。
一个 Assembly 里可以包含多个类型,由此可知,一个 Assembly 里也可以包含多个插件,就像前一篇文章所讲,只要它从 IPlugin 接口派生出来的类型,我们就承认它是一个插件类型。那么 Assembly 被动态加载了以后,我们如何获取 Assembly 里包含的插件实例呢?这就要用到反射( Reflection )机制了。我们需要使用 Assembly 的 GetTypes 静态方法来得到 Assembly 里所包含的所有的类型,然后遍历所有的类型并判断每一个类型是不是从 IPlugin 接口派生出来的,如果是,我们就使用 Activator 的静态方法 CreateInstance 方法来获得这个插件的实例。 .NET 的动态加载就是这几个步骤。下来,我做一个简单的例子来演练一下动态加载。首先声明一点,这个例子非常简单,纯粹是为了演练动态加载,我们的真正的插件式的应用程序框架里会有专门的 PluginService 来负责插件的加载,卸载。
我们的插件位于一个 DLL 里,所以我们首先创建一个 Class library 工程。创建一个 FirstPlugin 类让它派生于 IPlugin 接口,并实现接口的方法和属性,由于本文的目的是演示动态加载,所以 IPlugin 接口的 Loading 事件我们就不提供默认的实现了,虽然编译的时候会给出一个警告,我们不必理会它。这个插件的功能就是在应用程序里创建一个停靠在主窗体底部的 ToolStrip ,这个 ToolStrip 上有一个按钮,点击这个按钮,会弹出一个 MessageBox 显示“ The first plugin ”。下面是代码:
using
System;
using
System.Collections.Generic;
using
System.Text;
using
PluginFramework;
using
System.Windows.Forms;

namespace
FirstPlugin

{
public class FirstPlugin:IPlugin

{
private IApplication application = null;
private String name="";
private String description = "";


IPlugin Members#region IPlugin Members

public IApplication Application

{
get

{
return application;
}
set

{
application = value;
}
}

public string Name

{
get

{
return name;
}
set

{
name = value;
}
}

public string Description

{
get

{
return description;
}
set

{
description = value;
}
}

public void Load()

{
if (application != null && application.BottomToolPanel != null)

{
//创建一个向主程序添加的ToolStrip
ToolStrip sampleToolStrip = new ToolStrip();
ToolStripButton button = new ToolStripButton("Click Me");
button.Click += new EventHandler(button_Click);
sampleToolStrip.Items.Add(button);

//在主程序的底端添加ToolStrip
application.BottomToolPanel.Controls.Add(sampleToolStrip);
}
}

void button_Click(object sender, EventArgs e)

{
MessageBox.Show("The first plugin");
}

//相关的文章主要讲动态加载,所以卸载就不实现了
public void UnLoad()

{
throw new Exception("The method or operation is not implemented.");
}

public event EventHandler<EventArgs> Loading;

#endregion
}
}
private
void
toolStripButton1_Click(
object
sender, EventArgs e)

{
//动态加载插件,为了方便起见,我直接给出插件所在的位置
String pluginFilePath = Path.GetDirectoryName(Application.ExecutablePath) + "\\plugins\\FirstPlugin.dll";
Assembly assembly = Assembly.LoadFile(pluginFilePath);

//得到Assembly中的所有类型
Type[] types = assembly.GetTypes();

//遍历所有的类型,找到插件类型,并创建插件实例并加载
foreach (Type type in types)

{
if (type.GetInterface("IPlugin") != null)//判断类型是否派生自IPlugin接口

{
IPlugin plugin = (IPlugin)Activator.CreateInstance(type);//创建插件实例
plugin.Application = this;
plugin.Load();
}
}

}
一个 Assembly 里可以包含多个类型,由此可知,一个 Assembly 里也可以包含多个插件,就像前一篇文章所讲,只要它从 IPlugin 接口派生出来的类型,我们就承认它是一个插件类型。那么 Assembly 被动态加载了以后,我们如何获取 Assembly 里包含的插件实例呢?这就要用到反射( Reflection )机制了。我们需要使用 Assembly 的 GetTypes 静态方法来得到 Assembly 里所包含的所有的类型,然后遍历所有的类型并判断每一个类型是不是从 IPlugin 接口派生出来的,如果是,我们就使用 Activator 的静态方法 CreateInstance 方法来获得这个插件的实例。 .NET 的动态加载就是这几个步骤。下来,我做一个简单的例子来演练一下动态加载。首先声明一点,这个例子非常简单,纯粹是为了演练动态加载,我们的真正的插件式的应用程序框架里会有专门的 PluginService 来负责插件的加载,卸载。
我们的插件位于一个 DLL 里,所以我们首先创建一个 Class library 工程。创建一个 FirstPlugin 类让它派生于 IPlugin 接口,并实现接口的方法和属性,由于本文的目的是演示动态加载,所以 IPlugin 接口的 Loading 事件我们就不提供默认的实现了,虽然编译的时候会给出一个警告,我们不必理会它。这个插件的功能就是在应用程序里创建一个停靠在主窗体底部的 ToolStrip ,这个 ToolStrip 上有一个按钮,点击这个按钮,会弹出一个 MessageBox 显示“ The first plugin ”。下面是代码:



















































































































接下来我们创建一个
Windows Application
工程让主窗体派生于
IApplication
接口并实现
IApplication
接口的方法和属性,下来我们声明
1
个
MenuStrip
和
1
个
StatusStrip
,让他们分别停靠在窗口的顶部和底端,接下来我们声明
4
个
ToolStripPanel
,分别人他们停靠在上下左右四个边,最后我们创建一个
ToolStrip,
在上边添加一个按钮,当点击这个按钮的时候,我们动态的加载插件。
为了方便演示,我们把生成的 Assembly 放置到固定的位置,以方便主程序加载,在本例里,我们在应用程序所在的文件夹里创建一个子文件夹 Plugins ( E:\Practise\PluginSample\PluginSample\bin\Debug\Plugins ),将插件工程产生的 Assembly ( FirstPlugin.dll )放置在这个子文件夹。下面是动态加载的代码:
为了方便演示,我们把生成的 Assembly 放置到固定的位置,以方便主程序加载,在本例里,我们在应用程序所在的文件夹里创建一个子文件夹 Plugins ( E:\Practise\PluginSample\PluginSample\bin\Debug\Plugins ),将插件工程产生的 Assembly ( FirstPlugin.dll )放置在这个子文件夹。下面是动态加载的代码:



























我把完整源代码也附上,方便大家使用:源代码下载
<?XML:NAMESPACE PREFIX = O />
转载于:https://blog.51cto.com/kelenok/616027