我已经编写了一个vb.net Windows窗体应用程序,该应用程序基本上可以使用户将来自多个源的数据加载到网格上,对行和列执行数学和逻辑运算,然后导出结果。
一些用户要求提供仅他们需要的功能,我很乐意提供。但是,这导致了该应用程序的多个版本以及各种各样的维护问题。
我想通过制作标准版本的应用程序来解决此问题,从而能够向要求自定义功能的用户发送某种补丁以升级其版本。我的第一个想法是将需要动态处理的部分代码放在.dll中,并提供某种接口以从应用程序内部更改dll版本。那有可能吗?还是应该转向一些安装程序软件来完成此任务?
我不是在这里寻找食谱,只是朝着正确的方向轻推即可开始。欢迎任何建议或警告!
答案 0 :(得分:1)
是的,您可以创建一个加载项体系结构。您必须至少创建三个程序集,即Visual Studio中的项目。当然,您需要主要的Winforms应用程序作为可执行文件。
然后,您需要一个声明接口的类库。这些接口必须定义外接程序可以做什么。我只能给您一个很粗糙的印象,因为具体细节在很大程度上取决于外接程序必须执行的操作。您可能会有一个非常基本的外接程序定义,如下所示:
Public Interface IAddIn
ReadOnly Property Name As String
ReadOnly Property Version As String
End Interface
当然,这样的外接程序不能做很多事情,但是它允许可执行文件将类标识为外接程序,并在关于对话框中列出其名称和版本。您可以直接向此界面添加其他功能,也可以为不同类型的加载项创建不同的界面。例如。如果加载项要将其自己的菜单项添加到现有菜单,则可以让其实现此接口(除了IAddIn
之外):
Public Interface IMenuItemProvider
ReadOnly Property MenuItems As IEnumerable(Of ToolStripMenuItem)
End Interface
您可以定义数学函数或任何您需要的东西。
然后,您可以创建一个带有外接程序类的类库项目。主可执行文件和加载项都必须通过接口引用项目。这将在可执行文件和加载项之间建立一个界限。
可执行文件需要一些代码来加载加载项。我已将此代码放入类中。 (我已将其从C#转换为VB而不进行测试):
Public Class AddInLoader
Public Function Load(ByVal folder As String) As IList(Of IAddIn)
Dim addIns = New List(Of IAddIn)()
Dim files As String() = Directory.GetFiles(folder, "*.dll")
For Each file As String In files
addIns.AddRange(LoadFromAssembly(file))
Next
Return addIns
End Function
Private Shared Iterator Function LoadFromAssembly(ByVal fileName As String) As IEnumerable(Of IAddIn)
Dim asm As Assembly = Assembly.LoadFrom(fileName)
Dim addInInterfaceName As String = GetType(IAddIn).FullName
For Each type As Type In asm.GetExportedTypes()
Dim interfaceType As Type = type.GetInterface(addInInterfaceName)
If interfaceType IsNot Nothing AndAlso (type.Attributes And TypeAttributes.Abstract) <> TypeAttributes.Abstract Then
Dim addIn As IAddIn = CType(Activator.CreateInstance(type), IAddIn)
Yield addIn
End If
Next
End Function
End Class
使用此类,您可以像这样加载加载项
Dim loader = New AddInLoader()
Dim addIns As IList(Of IAddIn) = loader.Load(myAddInFolder)
For Each addIn As IAddIn In addIns
Dim menuProvider = TryCast(addIn, IMenuItemProvider)
If menuProvider IsNot Nothing Then
For Each menuItem As ToolStripMenuItem In menuProvider.MenuItems
//TODO: Add menu item to application menu
Next
End If
Next