如何在多项目解决方案中使用.net核心依赖注入?

Dab*_*bas 2 dependency-injection castle-windsor .net-core asp.net-core

我是asp.net核心的新手.
我正在尝试做的是构建多项目解决方案并使用依赖注入来传递项目之间的接口.
我所知道的是,在ASP.NET核心项目中,我们有文件中的ConfigureServices方法startup.cs来注册我们的接口及其实现,如下所示:

 public void ConfigureServices(IServiceCollection services)
 {
   // Add framework services.
   services.AddMvc();
   services.AddTransient<IMyInterface,MyImplementation>();
   .....
 }
Run Code Online (Sandbox Code Playgroud)

如果您在同一个项目中拥有所有类,那么这很好,但如果我有多个项目怎么办?
通常我要做的是与安装程序(Windsor安装程序)创建单独的项目,以注册所需的接口及其实现.

在.net核心中,我们可以通过创建静态ServiceCollection();并从中获取静态IServiceProvider来随时使用它来获取您注册的任何服务:

public static IServiceCollection _serviceCollection { get; private set; }
public static IServiceProvider serviceProvider { get; private set; }
public static RegisterationMethod() {
   _serviceCollection = new ServiceCollection();

   _serviceCollection.AddSingleton<IMyInterface,MyImplementation>();
   .....
   serviceProvider = _serviceCollection.BuildServiceProvider();
}

public T GetService<T>() where T : class
{
   return serviceProvider.GetService<T>();
}
Run Code Online (Sandbox Code Playgroud)

现在我们RegisterationMethod从ower启动项目调用并继续像往常一样开发,始终在此类中注册服务.
这种方法的问题是,如果我在ASP.NET核心项目中使用它,我将有两个地方来注册服务,这一个和startup.cs文件中的一个ConfigureServices(IServiceCollection services).
你可以说,

OK过关IServiceCollection,你必须在ConfigureServices(IServiceCollection services)RegisterationMethod你以前创建的,这样你正在使用的ASP.NET使用相同的服务集合.

但是通过这种方式,我将紧密耦合到依赖注入模块.net core.

有更干净的方法吗?或者我应该更换默认的DI Windsor吗?

Sha*_*tin 8

...在ASP.NET核心项目[s]中,我们有ConfigureServices ...来注册我们的接口及其实现...如果你在同一个项目中都有类,那么这很好,但如果我有多个项目怎么办?

你有多个项目并不重要.同样的原则适用:

将组合根放在应用程序中,尽可能靠近入口点.

让我们假设您有一个引用多个类库的应用程序.在应用程序的Startup类中,用于ConfigureServices注册所有依赖项.在每个类库项目中,使用构造函数注入.您的课程是在同一个项目还是在不同的项目中并不重要.

OK将您在ConfigureServices(IServiceCollection服务)中的IServiceCollection传递给之前创建的RegisterationMethod,这样您就可以使用ASP.NET使用的相同服务集合.

是的,这是做到这一点的方式.以下是github.com/aspnet/logging存储库中的示例:

public static IServiceCollection AddLogging(this IServiceCollection services)
{
    if (services == null)
    {
        throw new ArgumentNullException(nameof(services));
    }

    services.TryAdd(ServiceDescriptor.Singleton<ILoggerFactory, LoggerFactory>());
    services.TryAdd(ServiceDescriptor.Singleton(typeof(ILogger<>), typeof(Logger<>)));

    return services;
}
Run Code Online (Sandbox Code Playgroud)

根据你的评论......

...听起来你正试图避免在你的应用程序中使用组合根.组合根是我们向依赖注入容器注册依赖项的单个位置.组合根尽可能靠近应用程序的入口点(ConfigureServices例如,方法),它属于应用程序而不是其库中.

  • 我有asp.net核心项目,以及多层:(服务,存储库,...),你建议的方式是引用我在这个web项目中的所有接口和实现,我不这是一个很好的方法来做到这一点对 ?这就是为什么我想创建单独的项目来注册所有这些. (3认同)
  • @Dabbas:应用程序是您连接DI的地方,因为从应用程序到应用程序,它可能会因您使用它而有所不同,因此无法让库处理/引导它们自己.ASP.NET核心库通常在`AddXxx()`方法和`.UseXxx`(中间件注册)后面抽象它,所以你可以在你的Startup类中做`services.AddMyAppBusinessServices()`等.没有开箱即用的模块支持,如Unity或Windsor,您必须编写扩展方法或您自己的模块系统或使用第三方IoC容器 (2认同)