1

从一个页面我调用这样的服务:

_ = _importUserService.AddManyUserAsync(ValidatedUsers);

我希望 Page() 返回并让用户/用户界面继续前进,同时该服务在后台使用 UserManager 添加许多用户。问题是一旦 Page() 返回并且请求完成,IdentityDbContext 就会关闭并且 UserManager 不再起作用。请求完成后如何保持 UserManager 工作?

该服务使用标准依赖注入:

    private readonly UserManager<ApplicationUser> _userManager;

    public ImportUserService(UserManager<ApplicationUser> userManager)
    {
        _userManager = userManager;
    }

如果我使用 await 而不是 discard 并强制服务在页面加载之前完成,它工作正常;但是,如果用户需要等待 2 分钟才能在页面加载之前导入数千个用户,这将是糟糕的 UX。我的问题是没有创建存储过程并复制 UserManager 正在做的事情,有没有办法在其中使用 UserManager不依赖于请求生命周期的服务?

我的想法是创建一个新的 UserManager 实例,而不是依赖依赖注入中的实例,但到目前为止我还无法让它工作。不确定语法是什么,也找不到在 .net core 3.1 中实际工作的示例

如何在请求后使 IdentityDbContext 保持活动状态,以便服务可以使用 UserManager 完成其任务?(.Net Core 3.1)

4

1 回答 1

0

从文档

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 -任务

这允许我运行一个后台服务,该服务可以调用使用 UserManager 的服务

using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            })
            .ConfigureServices(services =>
            {
                services.AddHostedService<ConsumeScopedServiceHostedService>();
            });
}
public class ConsumeScopedServiceHostedService : BackgroundService
{
    private readonly ILogger<ConsumeScopedServiceHostedService> _logger;

    public ConsumeScopedServiceHostedService(IServiceProvider services, 
        ILogger<ConsumeScopedServiceHostedService> logger)
    {
        Services = services;
        _logger = logger;
    }

    public IServiceProvider Services { get; }

    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        _logger.LogInformation(
            "Consume Scoped Service Hosted Service running.");

        await DoWork(stoppingToken);
    }

    private async Task DoWork(CancellationToken stoppingToken)
    {
        _logger.LogInformation(
            "Consume Scoped Service Hosted Service is working.");

        using (var scope = Services.CreateScope())
        {
            var scopedProcessingService = 
                scope.ServiceProvider
                    .GetRequiredService<IScopedProcessingService>();

            await scopedProcessingService.DoWork(stoppingToken);
        }
    }

    public override async Task StopAsync(CancellationToken stoppingToken)
    {
        _logger.LogInformation(
            "Consume Scoped Service Hosted Service is stopping.");

        await base.StopAsync(stoppingToken);
    }
}

并且工作在 IScopedProcessingService > DoWork(stoppingToken) 中完成,这意味着 ScopedProcessingService 可以访问与使用我的问题中显示的依赖注入的典型 Web 服务相同的服务。

于 2021-03-15T01:54:33.013 回答