依赖注入和库/框架

时间:2012-08-14 06:46:52

标签: c# dependency-injection unity-container

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

问题

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

  • 服务器
  • 桌面客户端
  • 某些控制台实用程序
  • .NET API(单独的程序集,根类称为MyAppAPI
  • COM API(相同的,单独的程序集,您可以通过Set api = CreateObject("MyApp.MyAppAPI")
  • 访问API,例如VBScript
  • Java API(同样)
  • 消息传递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容器等。)
  • 当有人要求新的shell(通过Get方法)时,ShellBase检查是否已有这样的容器(或超级容器,来自子类),并返回该实例。或者创建新的

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

可能的解决方案

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

那么,伙计们,你觉得怎么样?

1 个答案:

答案 0 :(得分:0)

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),从而强制执行单例要求。

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