修补程序以支持多个版本的应用程序

时间:2018-10-30 20:12:12

标签: vb.net dynamic dll

我已经编写了一个vb.net Windows窗体应用程序,该应用程序基本上可以使用户将来自多个源的数据加载到网格上,对行和列执行数学和逻辑运算,然后导出结果。

一些用户要求提供仅他们需要的功能,我很乐意提供。但是,这导致了该应用程序的多个版本以及各种各样的维护问题。

我想通过制作标准版本的应用程序来解决此问题,从而能够向要求自定义功能的用户发送某种补丁以升级其版本。我的第一个想法是将需要动态处理的部分代码放在.dll中,并提供某种接口以从应用程序内部更改dll版本。那有可能吗?还是应该转向一些安装程序软件来完成此任务?

我不是在这里寻找食谱,只是朝着正确的方向轻推即可开始。欢迎任何建议或警告!

1 个答案:

答案 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