使用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)
该操作您需要新建一个解决方案
以下为引用的内容: 1Imports System.Data 2Imports System.Data.SqlClient 3Imports System.Net 4Imports System.IO 5Imports na7Interface.IPlugin 6 7Public Class recv 8 9 Implements IPlugin '实现此接口 10 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 17 Private Fir As String = "活动:" + MovementName + "(" + MovementID.ToString + ")" 18 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 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 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 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 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 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 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 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 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 116 Public Sub ResultText(ByVal txt As String) 117 '响应事件 118 RaiseEvent RaiseMyEvent(txt) 119 End Sub 120End 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年底花四个月时间写成的进销存系统,里面使用了插件机制生成的报表设计管理器,但没有使用到接口,而是预先定义好调用的方法。