如何在多项目解决方案中使用 .net 核心依赖注入? [英] How to use .net core dependency injection in multiprojects solution?

查看:41
本文介绍了如何在多项目解决方案中使用 .net 核心依赖注入?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm new to asp.net core.
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:

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

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

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.

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

In .net core we can do this by creating static ServiceCollection(); and get from it static IServiceProvider to use it any time to get any service you register:

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 文件中的一个地方,其中包含 配置服务(IServiceCollection 服务) .
你可能会说,

Now we call RegisterationMethod from ower startup project and continue to develop as usual with always registering the services in this class.
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) .
You may say,

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

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.

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

But in this way I'll be tight coupled to the dependency injection module of the .net core.

有没有更干净的方法来做到这一点?或者我应该用 Windsor 替换默认的 DI 吗?

Is there more clean way to do this ? or should I have replace the default DI with Windsor for example ?

推荐答案

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

...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?

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

It doesn't matter that you have multi projects. The same principle applies:

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

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

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. 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.

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

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.

是的,这就是这样做的方式.这是 .com/aspnet/logging 存储库:

Yes, that's the way to do it. Here is 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;
}

根据您的评论...

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

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.

这篇关于如何在多项目解决方案中使用 .net 核心依赖注入?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆