C# 依赖注入和库/框架

C# 依赖注入和库/框架,c#,dependency-injection,unity-container,C#,Dependency Injection,Unity Container,好吧,也许这里已经有这样的问题了,但我没有找到 问题 我们有很多入口点的大型企业应用程序。应用程序包含以下部分: 服务器 桌面客户端 一些控制台实用程序 .NET API(单独的程序集,根类名为likeMyAppAPI) COM API(同一个单独的程序集,您可以通过Set API=CreateObject(“MyApp.MyAppAPI”) Java API(同样,相同) 消息传递API(单独的程序集,用于通过消息队列在层之间进行通信) 我们在这个应用程序中使用Unity作为DI容器。在服

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

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

  • 服务器
  • 桌面客户端
  • 一些控制台实用程序
  • .NET API(单独的程序集,根类名为like
    MyAppAPI
  • COM API(同一个单独的程序集,您可以通过
    Set API=CreateObject(“MyApp.MyAppAPI”)
  • Java API(同样,相同)
  • 消息传递API(单独的程序集,用于通过消息队列在层之间进行通信)
我们在这个应用程序中使用Unity作为DI容器。在服务器/桌面客户端/控制台实用程序等中,一切都很酷。-有非常具体的入口点,所以我们只是在那里初始化对象,初始化对象/依赖项树,一切都像一个符咒一样工作。问题在于我们的API

#1 如何处理库/框架中的DI

从上面的链接:

组合根是一个应用程序基础结构组件

只有应用程序应该具有组合根。库和 框架不应该

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

#2 我们有依赖项,最好是单例依赖项(例如,一些工厂控制所创建对象的生命周期)。但是,我们可以创建一些API对象的实例,如何在它们之间共享此单例实例?更重要的是,我们可以在同一域中创建一些.NET API对象实例和一个/多个COM API对象实例(如果您愿意,我可以在注释中解释)

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

  • 我有class
    ShellBase
  • 此类包含静态字段
    \u shell
    和公共静态方法
    Get
    Release
  • 容器之间存在层次结构(例如,API的容器继承自MessagingAPI,服务器和DesktopClient容器继承自.NET API容器等)
  • 当有人请求新的shell时(通过
    Get
    方法),
    ShellBase
    检查是否已经存在这样的容器(或者子类中的超级容器),并返回该实例。或者创建新的实例
我不喜欢这种方式,但这是我现在能想象到的最好的方式

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


那么,各位,你们觉得怎么样?

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

2:我不完全确定我是否理解您的问题,但大多数(如果不是全部的话)DI容器都支持单实例生存期范围,这意味着您的容器将只创建一个实例。例如,在ninject中,您将执行以下操作:

kernel.Bind<IFoo>()
   .To<Foo>()
   .InSingletonScope();
kernel.Bind()
.至()
.InSingletonScope();
或者,如果您想避免使用公共构造函数,您可以像不使用DI容器一样创建该类的静态单例实例。您可以使用返回该实例的工厂方法向容器注册单例实例。同样,ninject示例:

kernel.Bind<IFoo>()
    .ToMethod(c => Foo.Instance);
kernel.Bind()
.ToMethod(c=>Foo.Instance);
考虑到上面介绍的接口,您应该能够在API之间共享单个容器实例(假设您在给定的应用程序中使用多个API),从而强制执行singleton需求


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

非常感谢您的回答!当然,我知道如何在DI容器中定义单例实例。问题是:如何在API对象的不同实例之间共享DI容器?我想得越多,我就越明白,也许唯一可靠的方法是创建
API工厂
,但也许有人知道更好的方法?如果您为容器引入一个接口,如1所示,您可以通过将容器注入API或直接从容器解析API对象,在API对象之间共享同一个容器实例。我不确定您的确切意思通过API对象。另请参见DI抽象层。如何?@Sebastian非常感谢链接!我现在有了一些想法,将尝试实现它们。。