我正在开发一个严重依赖插件架构(*)的应用程序。 但是,我不确定用于插件之间依赖关系的设计模式,例如当插件A依赖于插件B时,可能有一些约束(插件B版本介于v1.05和v1.30左右)
到目前为止我的想法:
我可以为插件B指定一个永不改变的接口,并且插件只能引用此接口项目。然后,插件B可以通过版本控制以任何方式自由地实现它,并且最新的可用实现将被依赖注入所请求的接口。 这可能有效,但似乎定义一个非常适合特定插件功能的接口是有点不必要的;另外我想我必须坚持那个界面;我只能轻松地在未来的版本中增强插件实现,而不是界面。
我可以忽略接口,只是开发插件的实现。插件A的项目可以直接引用插件B的.dll。但据我所知,这会在用新版本替换插件B的.dll时导致错误,除非我在我的应用程序配置中添加显式版本重定向,不是吗?!
有没有最佳做法?我想这个问题与Nuget软件包的depdendencies非常相似 - 有没有人碰巧知道他们是如何解决它的?
由于
(*)如果重要,我的插件架构如下工作:我的所有插件都实现了一个接口IPlugin。 我的主应用程序然后扫描插件目录中的所有.dll,过滤掉所有实现IPlugin的类,并使用Ninject从IPlugin添加绑定到特定实现(最后,将有几个绑定可用于IPlugin,例如IPlugin - > Plugin1,IPlugin - > Plugin2等)。然后我使用Ninject请求/创建每个插件的单例实例并在我的主应用程序中注册它。这样,我的插件可以通过构造函数参数“请求”依赖项,Ninject / DI负责提供这些依赖项。
答案 0 :(得分:1)
据我所知,Nuget使用nuget包文件中存储的元数据跟踪库依赖项。如果我是你,我会避免实施任意限制。例如,如果您的某个插件开发人员想要创建有用类的共享支持库,该怎么办?
在我看来,插件应该是一个黑盒子的功能。如果插件需要另一个插件,那么它们应该通过标准化的消息传递平台而不是直接进行通信。
也就是说,您可以随时从您加载的库中删除所有接口实现,并将它们与您的插件挂钩。这样,插件开发人员可以“请求”这些接口以及插件的实现。
你需要处理大量的类库(我建议只挂钩插件构造函数中引用的Ninject接口)和潜在的冲突(两个插件可能期望相同接口的单独实现 - 这是主要原因我相信插件应该在内部处理,而不是希望外部插件管理器满足其设计时间期望。
在回答(2)时,只要您引用的方法和属性不更改名称或签名,使用DLL A的较新版本的DLL B就不会有任何问题。如果您更改了返回类型,从公共字段(首先不应该存在)更改为公共属性,更改方法上的参数或您在DLL A中从DLL B使用的类的任何性质,需要重新编译A.