vb.net - 补丁支持多个版本的应用程序
问题描述
我编写了一个 vb.net Windows 窗体应用程序,基本上,它允许用户将来自多个源的数据加载到网格上,对行和列执行数学和逻辑运算,然后导出结果。
一些用户要求只有他们需要的功能,我很乐意提供。但是,这会导致应用程序的多个版本和各种维护问题。
我想通过制作应用程序的标准版本来解决这个问题,能够向要求自定义功能的用户发送某种补丁来升级他们的版本。我的第一个想法是将需要动态的代码部分放入 .dll 中,并提供某种接口来从应用程序本身更改 dll 版本。那可能吗?或者我应该求助于一些安装软件来完成这个?
我不是在这里寻找食谱,只是朝着正确的方向轻推让我开始。欢迎任何建议或警告!
解决方案
是的,您可以创建插件架构。您必须至少创建三个程序集,即 Visual Studio 中的项目。当然,您需要将主要的 winforms 应用程序作为可执行文件。
然后你需要一个声明接口的类库。这些接口必须定义插件可以做什么。我只能给你一个非常粗略的印象,因为具体细节很大程度上取决于加载项必须做什么。您可以有一个非常基本的插件定义,如下所示:
Public Interface IAddIn
ReadOnly Property Name As String
ReadOnly Property Version As String
End Interface
当然,这样的插件不能做很多事情,但它允许可执行文件将一个类识别为插件,并在 about-dialog 中列出其名称和版本。您可以直接向此界面添加附加功能,也可以为不同类型的加载项创建不同的界面。例如,如果一个插件想要将它自己的菜单项添加到现有菜单中,您可以让它实现这个接口(除了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
推荐阅读
- java - Network 对象的 NetworkInfo.isConnected() 的替代方法(API 23 中已弃用)
- xml - POST_PRODUCT_DATA 调用中的 EUCompliance 数据不被接受
- python - 机器学习算法来查找相似或匹配的记录?
- php - 在函数中回显 get_post_meta()
- android - MediaStore contentResolver.insert() 在拍照时创建副本而不是替换现有文件(Android Q: 29)
- python - Python类型 - 如果它是None,有没有办法避免导入可选类型?
- ssl - 是否可以要求服务器*不*在其“服务器问候”中发送“证书请求”?
- assembly - 在 PIC 汇编中保留内存指令“Res”的使用
- machine-learning - 如何将 plot_importance 函数与 MultiOutputRegressor 一起使用?
- ios - Xcode 11,Vmware 中的错误当我在项目中添加 appicon 时,我收到此错误