2

我们在 .net 核心中有一个 API 项目,在 .net 核心中有一个库项目,我们在其中定义了后台进程(使用 IHosted 服务的后台服务)。

在 API 项目中,我们将后台服务的依赖注册为:

services.AddHostedService<MyBackgroundProcess>();

我们还有一些其他范围、瞬态和单例依赖项,例如:

services.AddScoped<IHttpClientService , HttpClientService>();
services.AddScoped<IUserService, UserService>();
services.AddTransient<IMyTransientService, MyTransientService>();
services.AddScoped<IMyScopeService, MyScopeService>();

在我们的后台服务项目中,在构造函数中,我们注入了一些作用域和瞬态依赖项(例如):

public MyBackgroundProcess(IHttpClientService iHttpClientService, IUserService iUserService, IMyTransientService iMyTransientServcie, IMyScopeService iMyScopeService)                                                      
        {
            _iHttpClientService = iHttpClientService;
            _iUserService = iUserService;
            _iMyTransientServcie = iMyTransientServcie;
            _iMyScopeService = iMyScopeService;
        }

我能够在 .net core 2.2 中解决这些作用域依赖项。我从我的 API 项目中获取所有这些值。当我从 API 项目调用我的后台服务时,正在调用后台进程构造函数。所以我得到了所有更新的依赖项。

当我将项目迁移到 .net core 3.1 时,问题就来了。现在我的依赖项为空。这些没有与我调用这些后台服务的 API 项目同步。我们正在使用.net core inbuild DI。IHostedService/Background 服务的构造函数在将应用程序部署到服务结构时被调用,它不会在从 API 调用后台进程时被调用。

我的 API 业务逻辑构造函数如下:

public MyAPIManager(IMyTransientService myTransientService, IMyScopeService myScopedService, IHostedService myBackGroundProcess1,
                                 IHostedService myBackgroundProcess2, IServiceProvider serviceProvider)
        {
            _myTransientService = myTransientService;
            _myScopedService = myScopedService;
            _myBackGroundService1 = myBackGroundService1 as MyBackgroundServiceA;
            _myBackGroundService2 = myBackGroundService2 as MyBackgroundServiceB;
            if (_myBackGroundService2 == null)
            {
                var services = serviceProvider.GetServices<IHostedService>();
                _myBackGroundService2 = services.First(o => o.GetType() == typeof(MyBackgroundServiceB)) as MyBackgroundServiceB;
            }
        }

在这里,我正在注入、作用域和瞬态依赖项以及 2 个后台服务。每当我从“ serviceProvider.GetServices() ”中获取 IHostedService 的实例时,在 .net core 2.2 中,它都会调用在我的 DI 中注册的所有 IHosted 服务的构造函数,但在 .net core 3.1 中它不会调用背景的构造函数服务。


更新 -

我尝试将我的后台服务注册为Transient而不是AddHostedService,如下所示:

services.AddTransient<IHostedService, MyBackgroundService1>();
 services.AddTransient<IHostedService, MyBackgroundService2>();

似乎它现在正在工作,每次我尝试解析类型时它都会调用构造函数:

var services = serviceProvider.GetServices<IHostedService>();
                _myBackgroundProcess1 = services.First(o => o.GetType() == typeof(MyBackgroundProcessA)) as MyBackgroundProcessA;

像这样注册 IHostedService 是否可取?会不会有什么影响?

4

1 回答 1

0

Schoooo Wheeeeee。

看起来你遇到了一场小型圣战。

这是链接和讨论:

https://github.com/dotnet/extensions/issues/553

“AddHostedService 不应该是单例。请不要进行这种重大更改,”

“这个线程非常奇怪。HostedServices 应该是单例而不是瞬态的。”

这似乎是您案例中的关键评论:

“因为它是我们所期望的最常见场景的帮手。如果这不适合您,请直接使用 DI 方法。”

以前的回应:

按照这个例子:

https://docs.microsoft.com/en-us/aspnet/core/fundamentals/host/hosted-services?view=aspnetcore-3.1&tabs=visual-studio#sumption-a-scoped-service-in-a-background -任务

services.AddHostedService<ConsumeScopedServiceHostedService>();
services.AddScoped<IScopedProcessingService, ScopedProcessingService>();

(上面的代码来自示例)

您必须注册您的依赖项

services.AddHostedService<MyBackgroundProcess>();

services.AddScoped<IHttpClientService , MyConcreteHttpClientService>();
services.AddScoped<IUserService, MyConcreteUserService>();
services.AddScoped<IMyTransientService, MyConcreteMyTransientService>();
services.AddScoped<IMyScopeService, MyConcreteScopeService>();

这(上面的)是..当然......如果您没有使用某种“自动扫描”解决方案。(您的 2.2 代码中是否有某种自动扫描解决方案??)

就像是

NetCore.AutoRegisterDi

https://www.thereformedprogrammer.net/asp-net-core-fast-and-automatic-dependency-injection-setup/

public static class NetCoreDiSetupExtensions
{
    public static void RegisterServiceLayerDi
        (this IServiceCollection services)
    {
        services.RegisterAssemblyPublicNonGenericClasses()
            .AsPublicImplementedInterfaces();
 
        //put any non-standard DI registration, e.g. generic types, here
    }
}

另一个链接:

最终,我认为这是一个问题:

https://github.com/aspnet/Hosting/blob/master/src/Microsoft.Extensions.Hosting.Abstractions/ServiceCollectionHostedServiceExtensions.cs#L18

于 2020-07-28T19:38:05.453 回答