Dependency injection 使用简单的注入器构建基于插件的应用程序

Dependency injection 使用简单的注入器构建基于插件的应用程序,dependency-injection,simple-injector,plugin-architecture,Dependency Injection,Simple Injector,Plugin Architecture,我的任务是编写一份技术规范(并在以后实现)一个将构建在几个子模块上的系统。子模块将部分并行开发,因此我真的希望避免每次添加或更新插件时重新启动整个系统。因为我已经在另一个项目中使用了Simple Injector,所以我计划在每个子模块中将其用于IoC。我的计划不是在将模块绑定在一起的核心中引入MEF(托管扩展框架)或MAF(托管插件框架),而是看看是否可以使用Simple Injector来处理模块 我的计划是使用FileSystemWatcher来监视插件目录,当检测到更改时,可以让Simp

我的任务是编写一份技术规范(并在以后实现)一个将构建在几个子模块上的系统。子模块将部分并行开发,因此我真的希望避免每次添加或更新插件时重新启动整个系统。因为我已经在另一个项目中使用了Simple Injector,所以我计划在每个子模块中将其用于IoC。我的计划不是在将模块绑定在一起的核心中引入MEF(托管扩展框架)或MAF(托管插件框架),而是看看是否可以使用Simple Injector来处理模块

我的计划是使用FileSystemWatcher来监视插件目录,当检测到更改时,可以让Simple Injector自己做,也可以使用我自己的解决方案。我已经阅读了讨论,但我相信我的用例是不同的

要求:

  • 核心系统作为Windows服务运行,应该避免一直重新启动
  • 每个模块负责在内部协调需要完成的工作(这可能是很多工作,因此不需要重新启动所有工作)
  • 整个系统是基于事件的。模块将向事件总线发送事件,以便其他模块可以根据事件做出反应(做自己的事情)。然而,模块也将被允许定期做一些事情。一个模块监听目录中的新文件,解析文件并将数据放入数据库。其他模块可能需要基于此新数据执行某些操作。另一个模块进行一些定期计算
  • 所有模块都将共享一个公共接口IModule,该接口将使核心系统能够启动和停止(处置)模块,如果我找不到其他方法,可能还会有一种方法来注册事件总线
  • 在系统重启(f.x.服务器重启)时,内核当然应该能够拾取所有现有模块
为了能够动态加载/重新加载程序集,我计划在单独的AppDomain中运行每个模块


是否可以使用简单的喷油器?还有其他想法吗?也许是我没有想到的事情。

这不是DI容器所能促进的事情。它们只是组成对象图。在我看来,您需要运行独立的进程或应用程序域(否则将无法重新加载它们)


这意味着DI容器将在该隔离域(即您的模块)内运行。在该模块内,您将使用您的容器,就像您一直使用它一样。这与简单喷油器没有什么不同。

因此,根据与史蒂文的通信,我决定寻找替代方案,并与我的首席技术官交谈。这导致了通过消息总线(Azure服务总线)进行通信的完全不同的体系结构(微服务-可能实现为Azure功能)。这符合所有要求,并且(使用Azure功能)确保我们只在发生应处理的事件时支付计算能力。

顺便说一句,我担心你会告诉我这一点。对我的设计方案还有其他想法/意见吗?我真正的问题是:你真的需要这么大的灵活性吗?不过,对于您的系统,我看不出应用程序应该继续运行的原因。这尤其是使用存储在持久队列中的事件的好处:当您重新启动时,没有人会注意到。即使你每天重启100次。我不认为像MEF和MAF这样的框架非常适合您试图实现的目标。它们处理插件,但您在这里谈论的是完整的有界上下文(完整的应用程序),“意外地”在同一进程中运行(但可能是不同的应用程序域)。谢谢您的输入。关于灵活性,也许你是对的。也许我目前的建议是过度设计了这个问题,仅仅在启动时使用DI就足够了(这意味着忽略“无重启”要求)。实际上,我也考虑过将每个模块放在一个单独的流程中,以保持其独立性,但我知道,单独的流程或应用程序域会使通信变得非常复杂。我想我必须和我的首席技术官谈谈……单独的应用程序域会使通信变得复杂。但是,如果您的唯一通信方式是通过事件(通过持久队列发送),那么这应该是一个无需思考的问题;您可以完全自由地在一个应用程序域、一个进程、一台机器或多台机器上运行所有内容。