C# 如何在带有插件的应用程序中使用接口的版本号?

C# 如何在带有插件的应用程序中使用接口的版本号?,c#,.net,dll,coding-style,C#,.net,Dll,Coding Style,我想写一个允许为它编写插件的程序。 该程序将包含SDK和一些DLL库,这些库将促进插件的开发 但是,我很确定,随着时间的推移,SDK会发生变化,因此需要为SDK和插件提供某种版本号。SDK由许多DLL组成 此外,我不希望插件开发人员能够忘记为该机制做一些必要的事情 我可以想出两种方法: 使用恒定编译时间int VERSION=1。每个插件都以某种方式(我不知道具体如何)接受这个常量,并将其作为编译时常量添加到DLL中。加载插件时 对所有SDK模块使用相同的AssemblyVersion。加载插

我想写一个允许为它编写插件的程序。
该程序将包含SDK和一些DLL库,这些库将促进插件的开发

但是,我很确定,随着时间的推移,SDK会发生变化,因此需要为SDK和插件提供某种版本号。SDK由许多DLL组成

此外,我不希望插件开发人员能够忘记为该机制做一些必要的事情

我可以想出两种方法:

  • 使用恒定编译时间int VERSION=1。每个插件都以某种方式(我不知道具体如何)接受这个常量,并将其作为编译时常量添加到DLL中。加载插件时

  • 对所有SDK模块使用相同的AssemblyVersion。加载插件时,请检查插件的程序集版本是否低于当前SDK程序集版本。在这种情况下,我需要以某种方式同步程序版本和SDK版本

所以,我不知道如何做到这两个


你知道吗?我根本不会介绍版本控制的概念。 如果您认为
主机需要什么:

  • 定位和加载插件的可能性
  • 通过向插件公开特性或从插件中恢复特性,可以与插件交互
如何管理
SDK
中的开发更改

首先:所有更改都必须尽可能向后兼容

如果不可能呢

嗯,
主机
在加载的插件中搜索公开的功能,如果找不到,它会得出3个可能的结论

  • 插件是为较新版本的
    Host
    编写的,但被旧版本使用

  • 插件是为较旧版本的
    Host
    编写的,但被较新版本使用

  • 它不是一个有价值的插件

  • 当然,您可以在插件的
    MainClass
    上包含所需的
    Host
    版本,如属性,并且
    Host
    可以搜索它,这有助于轻松识别可能的版本冲突。为什么可能,因为版本可能不同,但架构可以非常可靠,无需插件供应商更改其中的内容


    希望这能有所帮助。

    我根本不会引入版本控制概念。 如果您认为
    主机需要什么:

    • 定位和加载插件的可能性
    • 通过向插件公开特性或从插件中恢复特性,可以与插件交互
    如何管理
    SDK
    中的开发更改

    首先:所有更改都必须尽可能向后兼容

    如果不可能呢

    嗯,
    主机
    在加载的插件中搜索公开的功能,如果找不到,它会得出3个可能的结论

  • 插件是为较新版本的
    Host
    编写的,但被旧版本使用

  • 插件是为较旧版本的
    Host
    编写的,但被较新版本使用

  • 它不是一个有价值的插件

  • 当然,您可以在插件的
    MainClass
    上包含所需的
    Host
    版本,如属性,并且
    Host
    可以搜索它,这有助于轻松识别可能的版本冲突。为什么可能,因为版本可能不同,但架构可以非常可靠,无需插件供应商更改其中的内容


    希望这能有所帮助。

    创建一个抽象类,所有插件都必须实现该抽象类,并将您的版本检查逻辑放入其中,即一个函数,返回插件在初始化插件后调用的与插件兼容的主版本号、次版本号和内部版本号

    根据您希望检查版本的严格程度,您可以在应用程序中做出响应。(我还建议您在版本中使用SemVer,随着API的成熟,您将了解原因)


    这还允许您检查太旧或太新而无法在应用程序上运行的版本。

    创建一个所有插件都必须实现的抽象类,并将您的版本检查逻辑放入其中,即一个函数,该函数返回插件在初始化插件后调用的与插件兼容的主版本号、次版本号和内部版本号

    根据您希望检查版本的严格程度,您可以在应用程序中做出响应。(我还建议您在版本中使用SemVer,随着API的成熟,您将了解原因)


    这还允许您检查是否有太旧或太新的版本无法在应用程序上运行。

    根据@Andrey的要求,这是我对OQ的详细评论:

    插件(如插件程序集中的插件)通常包含一个classm,它实现了一个接口,如
    IMyPlugin

    在大多数情况下,此接口需要有一个类似于
    InitPlugin()
    的方法,该方法允许插件设置其结构等,即初始化

    此InitPlugin()本身最希望在主程序中调用RegisterPlugin()之类的函数,以便向应用程序注册其功能。这通常也是通过接口实现的,例如
    IMyPluginHost

    现在,只要您保持这些接口的通用性,使其本身不需要更改,您就可以使用以下顺序轻松添加版本握手:

    public interface IMyPluginHost
    {
      public int RegisterPlugin(int FunctionalityGroup, object WorkerBee, int MinSDKVersion, int MaxSDKVersion);
      ... //Whatever you need to allow the plugin to call into the app
    }
    
    public interface IMyPlugin
    {
      public int InitPlugin(IMyPluginHost myhost); //Return value is hust an error code
      ... //Whatever you need to allow the app to call into the plugin
    }
    
    现在,当应用程序决定加载插件时,它将创建其内部插件宿主类,该类实现
    IMyPluginHost
    ,然后物理加载插件,向其类获取
    IMyPlugin
    ,并调用

    ((IMyPlugin)pluginClass).InitPlugin(this)
    
    插件现在可以循环使用其功能组(其中的功能组取决于您的应用程序-如果是图像处理应用程序,则可能有一些功能组,例如过滤器、FileTypeImport、FileTypeExport、笔刷等,每个功能组都有其接口)a
    host.RegisterPlugin(FunctionalityGroup, WorkerBee, MinSDKVersion, MaxSDKVersion);