IPluginsApplication
Event
Display(
sender
As
Object
,
e
EventArgs)
Property
Caption()
String
DisplayInput(
Text
String
)
在例子中我们简单定义了一个事件、一个属性和一个方法。插件程序在开发的时候只要引用了我们的“插件服务”接口就可以调用里面定义的内容了。
第二步,建立宿主程序。
但是光有接口是不能执行里面的内容的,必须要有一个实现了这个接口的实例才可以。这里我们让宿主程序实现这个接口,并且实现这些接口里面的内容,让插件程序可以进行操作。
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Class
Form1
Implements
PluginsInterface.IPluginsApplication
Event
System.EventArgs)
PluginsInterface.IPluginsApplication.Display
Property
String
Implements
PluginsInterface.IPluginsApplication.Caption
Get
Return
Me
.Text
Get
Set
(
value
)
Me
.Text = value
Set
Property
Sub
)
PluginsInterface.IPluginsApplication.DisplayInput
MsgBox(
"输入内容:"
& Text)
Sub
Private
Button1_Click(
System.
Object
Handles
Button1.Click
RaiseEvent
New
EventArgs)
.DisplayInput(
.TextBox1.Text)
Sub
Class
|
我们用一个标准的Windows窗体来实现“插件服务”接口的内容。通过Caption属性可以更改窗体的标题,通过DisplayInput方法可以显示字符串。
这样我们的宿主程序由于实现了“插件服务”接口,就可以通过“插件服务”接口来将实例传递进插件程序。我们回到“插件标识”接口的Connect方法,插件的入口函数参数将宿主程序通过“插件服务”接口的实例传递到插件程序内,使得插件程序可以调用宿主程序开放的内容。而且由于通过接口传递,这些操作都是类型安全的。
第三步,寻找并启动插件。
插件程序将会以动态链接库的形式提供,这就需要我们的宿主程序找到插件程序的文件,判断是不是合法的插件,实例化并且启动。
首先我们必须定义一个插件存放的路径,比如运行目录下面的Plugins目录。然后寻找这一目录下面所有的dll文件进行判断。限于篇幅的原因,我们这里使用绝对路径来代替。 对于找到的文件,通过反射我们就可以得到定义于这个dll文件中的所有类定义信息。通过刚才我们说的“插件标识”接口逐个判断,将实现了“插件标识”接口的类作为我们判断合法的插件类。然后使用实例化方法进行实例化。(注意,我们的插件程序默认一个无参数的实例化方法。)通过强制类型转换,将这个Object的实例转化为我们的“插件标识”接口实例,也就是IPlugins。由于此前我们已经判断过了,这个类实现了“插件标识”接口(也就是IPlugins接口),所以这个转换是安全的。最后通过IPlugins的Connect方法启动接口程序,将宿主程序,也就是我们的窗体实例通过参数传递。(由于我们的窗体已经实现了接口IPluginsApplication,所以这步操作也是安全的。)此后,程序将由插件接管,对于宿主程序,插件和宿主自己同时进行操作。
14
Dim
pobj
PluginsInterface.IPlugins
Button2_Click(
Button2.Click
ass
Reflection.
Assembly
= Reflection.
.LoadFile(
"E:Visual Sutdio Project 2005PluginsApplicationPluginsbinDebugPlugins.dll"
)
t
Type =
Nothing
For
Each
In
ass.GetTypes
If
t.IsClass
AndAlso
t.GetInterface(
GetType
(PluginsInterface.IPlugins).FullName,255)!important">True
) IsNot
Nothing
Then
Exit
For
If
Next
t IsNot
Then
pobj = ass.CreateInstance(t.FullName,monospace!important; min-height:inherit!important">)
pobj.Connect(
)
If
Sub
|
第四步,制作插件。
将一个类实现“插件标识”接口,用来表示这个类是宿主程序可识别的插件。同时必须实现Connect方法。通过Connect的参数,插件程序可以使用宿主程序通过“插件服务”接口提供的功能。
14
Plugins1
PluginsInterface.IPlugins
WithEvents
m_papp
PluginsInterface.IPluginsApplication
PluginsInterface.IPluginsApplication)
PluginsInterface.IPlugins.Connect
"插件启动成功。"
)
.m_papp = PluginsApp
.m_papp.Caption = InputBox(
"请输入宿主程序的窗体标题"
)
.m_papp.DisplayInput(InputBox(
"请输入字符串"
))
Sub
m_papp_Display(
m_papp.Display
f
New
Form1
f.ShowDialog()
Sub
通过上述方法,我们就制作完成了一个简单的插件。
总结一下:
(1) 通过接口定义插件的标识,进行类型验证并启动插件程序。这样做的好处是统一了插件的类型并且可以安全的进行启动。
(2) 通过接口定义宿主程序希望公开的功能。这样做一方面保证了宿主程序不会被插件程序完全的控制,另一方面让插件程序可以安全的运行宿主提供的方法。缺点是宿主程序如果有多层嵌套的类关系需要开放的话,需要将所有的类都重新通过接口进行封装。
(3) 宿主程序、插件程序引用统一的接口程序,将插件的开发了宿主程序本身脱离,提高宿主的安全性,并且防止了循环引用的发生。 (编辑:李大同)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|
|