2

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

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

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

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

有什么想法或指导吗?

4

2 回答 2

3

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

于 2013-01-17T05:22:21.173 回答
3

因此,您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来实现这一点。

于 2013-01-17T05:32:37.557 回答