使用asp.net或vb.net或C#.net均可以实现插件的功能,插件的作用是对系统的后期未知扩展预留快速升级的空间,在程序中通过遍历该文件夹中的所有DLL检测符合预定接口的插件来实现动态装载相应的功能模块。
使用asp.net或vb.net或C#.net均可以实现插件的功能,插件的作用是对系统的后期未知扩展预留快速升级的空间!插件开发完成后将以DLL的形式发布到特定的文件夹中,例如主程序文件夹是D:\myApp\myApp.exe,我们可以在D:\myApp中定义文件夹D:\myApp\Plus目录来存放插件。
在程序中通过遍历该文件夹中的所有DLL检测符合预定接口的插件来实现动态装载相应的功能模块!
下面举例:
一、定义接口
新建解决方案用于生成此接口
以下为引用的内容:
1 Public Class IPlugin
2 Public Interface IPlugin
3 Property MovementID() As Integer
4 Property MovementName() As String
5 Property ReTryMinute() As Integer
6 Property ConnectionString() As String
7 Event RaiseLog(ByVal log As String)
8 Sub Init()
9 End Interface
10 End Class |
二、编写继承自该接口的自定义组件(将编译成DLL)
该操作您需要新建一个解决方案
以下为引用的内容:
1 Imports System.Data
2 Imports System.Data.SqlClient
3 Imports System.Net
4 Imports System.IO
5 Imports na7Interface.IPlugin
6![](http://www.chinaz.com/upimg/allimg/090504/1521090.gif)
7 Public Class recv
8![](http://www.chinaz.com/upimg/allimg/090504/1521097.gif)
9 Implements IPlugin '实现此接口
10![](http://www.chinaz.com/upimg/allimg/090504/1521097.gif)
11 '构造属性变量
12 Private _MovementID As Integer = 27
13 Private _MovementName As String = "51麦克疯"
14 Private _SpanMinute As Integer = 30
15 Private _ConnectionString As String = ""
16![](http://www.chinaz.com/upimg/allimg/090504/1521097.gif)
17 Private Fir As String = "活动:" + MovementName + "(" + MovementID.ToString + ")"
18![](http://www.chinaz.com/upimg/allimg/090504/1521097.gif)
19 ''' <summary>
20 ''' 返回内部处理的消息,实现接口中的RaiseLog事件。
21 ''' </summary>
22 ''' <param name="logText"></param>
23 ''' <remarks></remarks>
24 Public Event RaiseMyEvent(ByVal logText As String) Implements IPlugin.RaiseLog
25![](http://www.chinaz.com/upimg/allimg/090504/1521097.gif)
26 ''' <summary>
27 ''' 调用此方法!
28 ''' </summary>
29 ''' <remarks></remarks>
30 Public Sub Init() Implements IPlugin.Init '继承自接口的Init方法。
31 '这里放置数据抓取及相关的处理程序。
32 '实际应用中要根据您的程序何时调用Init决定,这不是必须的方法
33 ResultText("处理完成!")
34 End Sub
35![](http://www.chinaz.com/upimg/allimg/090504/1521097.gif)
36 Private Sub SaveSetups(ByVal savedate As String, ByVal UserID As String, ByVal WebId As String, ByVal Setups As String)
37 '定义该内部方法,这个方法不实现任何接口中的方法。因此只在本类内部实现。
38 Dim CmdText As String = ""
39 End Sub
40![](http://www.chinaz.com/upimg/allimg/090504/1521097.gif)
41 ''' <summary>
42 ''' 返回八位数字的日期格式
43 ''' </summary>
44 ''' <param name="dt"></param>
45 ''' <returns></returns>
46 ''' <remarks></remarks>
47 Private Function ClongDate(ByVal dt As Date) As String '同上
48 Dim mm As String = dt.Month.ToString
49 If mm.Length = 1 Then mm = "0" + mm
50 Dim dd As String = dt.Day.ToString
51 If dd.Length = 1 Then dd = "0" + dd
52 Return dt.Year.ToString + "" + mm + dd
53 End Function
54![](http://www.chinaz.com/upimg/allimg/090504/1521097.gif)
55 Private Function ConvDate(ByVal dt As Long) As String '同上
56 Dim YY As String = Mid(dt.ToString, 1, 4)
57 Dim MM As String = Mid(dt.ToString, 5, 2)
58 Dim DD As String = Mid(dt.ToString, 7, 2)
59 Return YY + "-" + MM + "-" + DD + " 00:00:00"
60 End Function
61![](http://www.chinaz.com/upimg/allimg/090504/1521097.gif)
62 ''' <summary>
63 ''' 获得此组件处理的活动ID,该属性实现了接口IPlugin的MovementID属性。
64 ''' </summary>
65 ''' <value></value>
66 ''' <returns></returns>
67 ''' <remarks></remarks>
68 Public Property MovementID() As Integer Implements IPlugin.MovementID
69 Get
70 Return _MovementID
71 End Get
72 Set(ByVal value As Integer)
73 _MovementID = value
74 End Set
75 End Property
76![](http://www.chinaz.com/upimg/allimg/090504/1521097.gif)
77 ''' <summary>
78 ''' 获得此组件的活动名称,同上
79 ''' </summary>
80 ''' <value></value>
81 ''' <returns></returns>
82 ''' <remarks></remarks>
83 Public Property MovementName() As String Implements IPlugin.MovementName
84 Get
85 Return _MovementName
86 End Get
87 Set(ByVal value As String)
88 _MovementName = value
89 End Set
90 End Property
91![](http://www.chinaz.com/upimg/allimg/090504/1521097.gif)
92 ''' <summary>
93 ''' 获得此组件定时调用的间隔分钟数,实现自定义属生ReTryMinute
94 ''' </summary>
95 ''' <value></value>
96 ''' <returns></returns>
97 ''' <remarks></remarks>
98 Public Property SpanMinute() As Integer Implements IPlugin.ReTryMinute
99 Get
100 Return _SpanMinute
101 End Get
102 Set(ByVal value As Integer)
103 _SpanMinute = value
104 End Set
105 End Property
106![](http://www.chinaz.com/upimg/allimg/090504/1521097.gif)
107 Public Property ConnectionString() As String Implements IPlugin.ConnectionString
108 Get
109 Return _ConnectionString
110 End Get
111 Set(ByVal value As String)
112 _ConnectionString = value
113 End Set
114 End Property
115![](http://www.chinaz.com/upimg/allimg/090504/1521097.gif)
116 Public Sub ResultText(ByVal txt As String)
117 '响应事件
118 RaiseEvent RaiseMyEvent(txt)
119 End Sub
120 End Class
|
三、在程序中调用定义的接口
注意:程序中定义接口编译生成的DLL必须使用同一个,否则如果不是使用相同的DLL,即使DLL的内容相同,同样也会产生错误。
以下为引用的内容:
Imports System.Data
Imports System.Data.SqlClient
Imports System.Reflection
Imports PlusFace.Face
Public Class ShowPlus
Inherits System.Web.UI.Page
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
loadPlus()
End Sub
Private Sub loadPlus()
'遍历Plus目录下的dll文件
dllFileName.Items.Add(New ListItem("请选择接口插件", ""))
Dim DirPath As String = Server.MapPath("..\Interface")
If IO.Directory.Exists(DirPath) = False Then
IO.Directory.CreateDirectory(DirPath)
End If
Dim DirectoryPath() As String
DirectoryPath = System.IO.Directory.GetFileSystemEntries(DirPath)
For Each file As String In DirectoryPath
If System.IO.File.Exists(file) = True Then
'判断此文件扩展名是否为dll
If LCase(Strings.Right(file, 4)) = ".dll" Then
'获得此文件信息及此组件的入口类名称与
Dim Ref As Assembly
Ref = Assembly.LoadFrom(file)
For Each typeTmp As Type In Ref.GetTypes
If typeTmp.IsPublic = True Then
'下面判断是否实现了接口,如果是,则取当前类型为该类实现的类型
Dim TypeGet As Type = typeTmp.GetInterface("Plus")
If IsNothing(TypeGet) = False Then
Dim asmName As String = System.IO.Path.GetFileNameWithoutExtension(file)
Dim t As Type = Ref.GetType(typeTmp.FullName) '这是区分大小写的。
Dim Obj As Plus = CType(Activator.CreateInstance(t), Plus)
'下面加载插件
Dim FileName As String = Replace(file, Server.MapPath("..\Interface\"), "")
Response.Write(Obj.InterfaceName + "(" + FileName + ")")
Exit For
End If
End If
Next
End If
Else
End If
Next
End Sub
End Class |
这里有本人2007年底花四个月时间写成的进销存系统,里面使用了插件机制生成的报表设计管理器,但没有使用到接口,而是预先定义好调用的方法。