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

时间:2016-10-22 19:55:07

标签: dependency-injection asp.net-core castle-windsor .net-core

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

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

如果您在同一个项目中拥有所有课程,这是很好的,但如果我有多个项目怎么办? 通常我要做的是与安装程序(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>();
}

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

  

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

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

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

1 个答案:

答案 0 :(得分:8)

  

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

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

将您的作品根目录放在应用程序中,尽可能靠近入口点。

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

  

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

是的,这是做到这一点的方法。这是an example from the github.com/aspnet/logging repository

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;
}

根据您的评论...

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