【问题标题】:DI Service with No Dependent Services无依赖服务的 DI 服务
【发布时间】:2013-01-17 03:18:29
【问题描述】:

我一直在与 Ninject 合作使用依赖注入来实现应用程序。我觉得我对这些概念有相当透彻的理解,并且非常喜欢应用程序使用 DI 实现的松散耦合和可测试架构。但是,我正在为一种特定类型的服务苦苦挣扎,并且正在寻找有关我是否做错了什么或其他人是否遇到过同样事情的洞察力。

基本上,我最终得到了一些没有其他服务依赖于它们的服务/类(数量非常少)。正因为如此,该类永远不会被实例化,即使它是必需的,因为它在应用程序中扮演着有用的角色。例如,假设我有一个IMonkeyRepository 服务和一个IMonkeyPopulator 服务。假设IMonkeyPopulator 服务确实没有公共API,它的唯一职责(遵循单一职责原则)是发现网络上的猴子并用它们填充IMonkeyRepository。该服务依赖于IMonkeyRepository 和可能的其他一些服务来处理它与网络的交互(例如,端口和地址的配置数据)。但是,IMonkeyPopulator 没有公共 API,它只是一个空接口。

这是一个糟糕的设计还是我遗漏了某种代码味道?我显然可以将此功能移动到存储库本身,但这对我来说似乎违反了 SRP(存储库具有有用的访问功能等,并且实际上可以由多个服务填充)。我考虑过或尝试过但不满意的一些方法是:

  1. 使服务具有一个公共方法,例如 Start,必须调用该方法才能开始工作。这样做的缺点是需要在系统中确定一个有点随意的位置来进行调用。
  2. 将服务绑定到我在创建 Ninject 内核时实例化的常量。这要求我了解没有人依赖此服务,因此必须对其进行特殊处理,这似乎是错误的。
  3. 向服务中添加一些成员,并在我的应用程序中的某处创建一个 GUI 来读取这些值(例如服务的状态等)。显然,必须向我的应用程序添加一个仅出于这个原因才存在的 GUI 是非常愚蠢的(尽管有时对调试等很有用)。

有什么想法或指导吗?

【问题讨论】:

    标签: c# dependency-injection inversion-of-control ninject ninject-2


    【解决方案1】:

    您说IMonkeyPopulator 依赖于IMonkeyRepository,但似乎应该反过来?听起来您的IMonkeyRepository 依赖于,因此可能需要注入IMonkeyPopulator。如果您还可以注入一些其他服务,但在内部,IMonkeyRepository 可以告诉IMonkeyPopulator “启动”,以便存储库中实际上有一些东西?我可能误解了这个问题......也许我不应该这么胡闹:/

    【讨论】:

    • 很有趣,但我认为这种方法会违反单一职责原则。假设我有多个填充器,我必须将它们全部注入存储库(并全部启动)。现在,无论何时出现新的填充器以及访问存储库中项目的方式需要更改时,存储库类都必须更改。更改类的多个原因表明违反了 SRP。话虽这么说,我认为这种方法可能和我想到的任何方法一样好。
    • 在这种情况下,我会注入一个像 IMonkeyPopulatorAggregate 这样的对象,并从存储库中调用它的 populate() 方法。如果我需要添加更多填充器,存储库代码根本不会改变。话虽如此,根据我的经验,为每一种可能的意外情况而不是手头的具体问题(也许你提到的场景是你的具体问题——我不知道)做计划就像在寻找兔子洞的底部。最后,一旦你真正理解了某个特定的规则/原则/模式/哲学/本月的味道,保留违反它的权利。
    【解决方案2】:

    因此,您的IMonkeyPopulator 是某种ActiveObject,它在后台侦听tcp 连接并将该数据写入存储库。我会从应用程序的角度说,必须启动和停止活动对象,因为您不想在构造函数中启动 tcp 连接。因此,您可以使用绑定上的OnActivationOnDeactivation 方法来启动和停止服务,如下所示:

     This.Bind<IPopulatorService>().To<>().OnActivation((c, i) => i.Start()).OnDeactivation((c, i) => i.Stop())
    

    但您的应用程序中仍然有人必须获取/获取IPopulatorService 才能在您的应用程序中实例化它。我通常在这里使用引导程序模式http://www.appccelerate.com/bootstrapper.html 来实现这一点。

    【讨论】:

    • 为什么说我不想在构造函数中启动 TCP 连接?
    • 我经常练习 TDD,如果您的对象易于构建且在创建期间不活动,它会更容易
    猜你喜欢
    • 1970-01-01
    • 2015-09-03
    • 2020-08-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-10
    • 1970-01-01
    相关资源
    最近更新 更多