简体   繁体   English

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

[英]How to use .net core dependency injection in multiprojects solution?

I'm new to asp.net core. 我是asp.net核心的新手。
What I'm trying to do is to build multi projects solution and use dependency injection to pass interfaces between projects. 我正在尝试做的是构建多项目解决方案并使用依赖注入来传递项目之间的接口。
What I know is that in ASP.NET core project we have ConfigureServices method in startup.cs file to register our interfaces and their implementations like this: 我所知道的是,在ASP.NET核心项目中,我们在startup.cs文件中有ConfigureServices方法来注册我们的接口及其实现,如下所示:

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

This is good if you have classes all in the same project, but what if I have multi projects ? 如果您在同一个项目中拥有所有类,那么这很好,但如果我有多个项目怎么办?
Usually what I'll do is create separate project with installers (Windsor installers) to register the needed interfaces and their implementations. 通常我要做的是与安装程序(Windsor安装程序)创建单独的项目,以注册所需的接口及其实现。

In .net core we can do this by creating static ServiceCollection(); 在.net核心中,我们可以通过创建静态ServiceCollection(); and get from it static IServiceProvider to use it any time to get any service you register: 并从中获取静态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>();
}

Now we call RegisterationMethod from ower startup project and continue to develop as usual with always registering the services in this class. 现在我们从ower启动项目调用RegisterationMethod并继续像往常一样开发,始终在此类中注册服务。
The problem in this approach is if I used it in ASP.NET core project I'll have two places to register the services, this one and the one in the startup.cs file which has ConfigureServices(IServiceCollection services) . 这种方法的问题是,如果我在ASP.NET核心项目中使用它,我将有两个位置来注册服务,这一个和startup.cs文件中的一个具有ConfigureServices(IServiceCollection services)
You may say, 你可以这样说,

OK pass IServiceCollection you had in ConfigureServices(IServiceCollection services) to the RegisterationMethod you previously created, in this way you're using the same services collection that ASP.NET using. OK过关IServiceCollection你曾在ConfigureServices(IServiceCollection services)RegisterationMethod你以前创建的,这样你正在使用的ASP.NET使用相同的服务集合。

But in this way I'll be tight coupled to the dependency injection module of the .net core . 但是通过这种方式,我将紧密耦合到.net core的依赖注入模块。

Is there more clean way to do this ? 有更干净的方法吗? or should I have replace the default DI with Windsor for example ? 或者我应该用Windsor替换默认的DI吗?

...in ASP.NET core project[s] we have ConfigureServices... to register our interfaces and their implementations... This is good if you have classes all in the same project, but what if I have multi projects? ...在ASP.NET核心项目[s]中,我们有ConfigureServices ...来注册我们的接口及其实现...如果你在同一个项目中都有类,那么这很好,但如果我有多个项目怎么办?

It doesn't matter that you have multi projects. 你有多个项目并不重要。 The same principle applies: 同样的原则适用:

Put your composition root in your application, as close to the entry point as possible. 将组合根放在应用程序中,尽可能靠近入口点。

Lets assume that you have a single application that references several class libraries. 让我们假设您有一个引用多个类库的应用程序。 In your application's Startup class, use ConfigureServices to register all of the dependencies. 在应用程序的Startup类中,使用ConfigureServices注册所有依赖项。 In each of the class library projects, use constructor injection. 在每个类库项目中,使用构造函数注入。 It does not matter whether your classes live in the same or in different projects. 您的课程是在同一个项目还是在不同的项目中并不重要。

OK pass IServiceCollection you had in ConfigureServices(IServiceCollection services) to the RegisterationMethod you previously created, in this way you're using the same services collection that ASP.NET using. OK将您在ConfigureServices(IServiceCollection服务)中的IServiceCollection传递给之前创建的RegisterationMethod,这样您就可以使用ASP.NET使用的相同服务集合。

Yes, that's the way to do it. 是的,这是做到这一点的方式。 Here is an example from the github.com/aspnet/logging repository : 以下是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;
}

Based on your comments... 根据你的评论......

...it sounds like you are trying to avoid having a composition root in your application. ...听起来你正试图避免在你的应用程序中使用组合根 The composition root is the single location where we register dependencies with the dependency injection container. 组合根是我们向依赖注入容器注册依赖项的单个位置。 The composition root is placed as close as possible to the application's entry point (the ConfigureServices method, for instance) and it belongs in the application not in its libraries. 组合根尽可能靠近应用程序的入口点(例如, ConfigureServices方法),它属于应用程序而不是其库中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM