gpt4 book ai didi

c# - 长期运行的 Windows 服务中的依赖注入(inject) - Composition root 是正确的想法吗?

转载 作者:太空狗 更新时间:2023-10-29 17:40:21 26 4
gpt4 key购买 nike

我正在编写一个 Windows 服务(如果一切按计划进行)将一次运行数月。在服务的整个生命周期中,它将维护几个 WCF 服务(用于与其他本地应用程序通信的命名管道),它将运行一个嵌入式数据存储(可能是 RavenDB,这或多或少与这个问题无关),并且它将使用某些第三方软件维护 SIP 服务(VoIP 功能)。我面临的一些挑战意味着必须对事件使用react并创建一些新的业务对象来处理这些事件所代表的内容。

现在,我已经阅读了 Mark Seemann 的书(至少是本次讨论的相关部分),并且我理解了为什么服务定位器不好,以及为什么在组合根(在我的案例中是服务起点)中处理它好 - 在一般情况下。

但是,我不明白这如何适用于所有情况。我看到在您可以在应用程序开始时组成整个根的情况下,或者在像 MVC 这样框架根据请求使用 IoC 引擎的情况下,它是多么完美。但是,对于长期运行的服务,我认为在最好的情况下效率低下,并且在某些情况下不可能预先创建所有对象。我无法想象能够编写一个重要的服务来获取它可能需要的所有对象,并且永远不需要随着生活的继续创建新对象。

现在,这还不足以将我引诱到黑暗面,并像服务定位器让我做的那样承担隐藏依赖的代价。但在这里做什么才是正确的呢?如果我有一个 CallHandlerService 需要创建以响应每个传入调用(例如因为它使用昂贵的非托管资源),我该怎么做呢?

组合根 + 只是一点服务定位器?

最后一部分并不严重,但我仍然很想知道如何正确解决这个问题。

最佳答案

可以将问题分成两部分:

  • 如何管理范围
    • 避免预先创建所有可能的依赖项
    • 创建所需的依赖项
  • 如何管理生命周期
    • 保留对已创建依赖项的引用
    • 如果可能,重用依赖项
    • 尽快清理它们

如何管理范围

您可以定义几个专门的抽象工厂的接口(interface)或实现,它们中的每一个都将仅限于管理仅它自己的特殊类型的依赖性。例如:一个与数据库相关的依赖关系,另一个与 SIP 相关。然后你可以自己注入(inject)工厂,而不是依赖项,并从中检索依赖项。

这听起来不像服务定位器吗?是的,但它不是服务定位器。您可以在 Mark Seemann blog: Abstract Factory or Service Locator? 阅读更多相关信息.

如果抽象工厂没问题,请查看 Ninject.Extensions.Factory根据您的 IKernel 配置自动创建它们

如何管理生命周期

如果您要 24-7 全天候运行您的服务,这是更复杂和重要的部分。在这里我只能给你几个实用的建议:

  • 对于此类服务,外部依赖端的故障(即数据库、服务)是例行公事,并非异常(exception)
  • 不要在代码中保留对依赖项的任何引用以提高性能或重用
  • 不要使用复杂的生命周期(例如 Ninject 的命名范围)
  • 尽快释放依赖项。配置 Ninject 为您管理它们。
  • 考虑依赖超时,重新创建新实例
  • 可能用于长时间运行的任务,创建单独的 Kernel 实例,并确保您已在之后处理它们

关于c# - 长期运行的 Windows 服务中的依赖注入(inject) - Composition root 是正确的想法吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16625694/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com