【问题标题】:Dependency injection and Libraries/Frameworks [duplicate]依赖注入和库/框架[重复]
【发布时间】:2012-08-14 06:46:51
【问题描述】:

好的,也许这里已经有这样的问题了,但我没有找到它..

问题

我们有很多入口点的大型企业应用程序。应用包含如下部分:

  • 服务器
  • 桌面客户端
  • 一些控制台实用程序
  • .NET API(独立程序集,根类称为MyAppAPI
  • COM API(相同的独立程序集,您可以通过Set api = CreateObject("MyApp.MyAppAPI")从例如VBScript访问API
  • Java API(同样)
  • Messaging API(单独的程序集,用于通过消息队列在层之间进行通信)

我们在这个应用程序中使用 Unity 作为 DI 容器。 Server/DesktopClient/Console 实用程序等中的一切都很酷 - 有非常具体的入口点,所以我们只需在那里初始化 composition root 对象,初始化对象/依赖关系树,一切都像魅力一样工作。他们的问题在于我们的 API。

#1

如何处理库/框架中的DI?

从上面的链接:

Composition Root 是一个应用程序基础架构组件。

只有应用程序应该有组合根。图书馆和 框架不应该。

是的,这很酷,但是.. 我想在我的 API 中使用 DI,它太棒了!如何处理一个与另一个?

#2

我们有依赖项,最好是单例(例如,一些工厂,它控制创建对象的生命周期)。但是,我们可以创建一些 API 对象的实例,如何在它们之间共享这个单例实例呢?甚至更多——我们可以在同一个域中创建一些 .NET API 对象的实例和一个/一些 COM API 对象的实例(如果你愿意,我可以在可能的情况下在评论中解释)..

我现在拥有的

正如我所说,应用程序没有问题,问题存在于库 (API) 中。所以,我现在拥有什么

  • 我有课ShellBase
  • 这个类包含静态字段_Shells和公共静态方法GetRelease
  • 容器之间存在层次结构(例如,API 的容器继承自 MessagingAPI,Server 和 DesktopClient 容器继承自 .NET API 容器等)
  • 当有人要求新的外壳(通过Get 方法),ShellBase 检查是否已经存在这样的容器(或超容器,来自子类),并返回该实例。或者创建一个新的

我不喜欢这种方式,但这是我现在能想象到的最好的方式。

可能的解决方案

创建类似APIFactory 的东西,这将创建我们的 API 对象,但它看起来......对于最终用户来说太复杂了。我不想在用户文档中写:“请先创建并保留 APIFactory 实例,然后您可以使用此工厂创建 API 实例”。它很丑。我们的用户应该只写var api = new API(),然后使用它。

那么,小伙伴们,你们觉得呢?

【问题讨论】:

  • this question 呢?
  • @Sebastian 非常感谢您的链接!我现在有了一些想法,并将尝试实施它们..

标签: c# dependency-injection unity-container


【解决方案1】:

1:我见过其他框架/库,它们通过接口引入自己的 DI 容器抽象。然后,他们在需要引用 DI 容器的任何地方都在内部使用此接口。适配器用于将其库与特定的 DI 容器连接起来。例如,Davy Brion 的 Agatha 项目具有以下 Container 接口:https://github.com/davybrion/Agatha/blob/master/Agatha.Common/InversionOfControl/IContainer.cs,他为最常用的 DI 容器提供适配器。

2:我不完全确定我是否理解您的问题,但大多数(如果不是全部)DI 容器都支持单例生命周期范围,这意味着您的容器只会创建一个实例。例如,在 ninject 中你会这样做:

kernel.Bind<IFoo>()
   .To<Foo>()
   .InSingletonScope();

或者,如果您想避免使用公共构造函数,您可以像没有 DI 容器那样创建该类的静态单例实例。您可以使用返回该实例的工厂方法向容器注册您的单例实例。同样,一个ninject示例:

kernel.Bind<IFoo>()
    .ToMethod(c => Foo.Instance);

鉴于上面介绍的接口,您应该能够在 API 之间共享单个容器实例(假设您在给定应用程序中使用多个 API),从而强制执行单例要求。

如果这不是你的问题,那么也许你可以详细说明第二个问题。

【讨论】:

  • 非常感谢您的回答!当然,我知道如何在 DI 容器中定义单例实例。问题是:如何在 API 对象的不同实例之间共享 DI 容器?我越想越明白,也许唯一可靠的方法是创建API factory,但也许有人知道更好的方法?
  • 如果您为容器引入一个接口,如 1 所示,您可以通过将容器注入 API 或直接从容器解析 API 对象来在 API 对象之间共享相同的容器实例。不过,我不确定您所说的 API 对象到底是什么意思..
  • 另请参阅Common Service Locator 了解 DI 抽象层。
猜你喜欢
  • 1970-01-01
  • 2011-06-12
  • 2014-09-06
  • 1970-01-01
  • 1970-01-01
  • 2010-09-14
  • 1970-01-01
  • 2010-12-31
  • 1970-01-01
相关资源
最近更新 更多