将 Context Ef core 注入到 Worker Service 项目

问题描述

我想将我的内容注入到项目中并在工作人员中使用上下文:

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

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureServices((hostContext,services) =>
                {
                    services.AddDbContext<XContext>(options =>
                    {
                        options.UsesqlServer(
                            hostContext.Configuration["ConnectionStrings:Connection"],serverDbContextOptionsBuilder =>
                            {
                                var minutes = (int)TimeSpan.FromMinutes(3).TotalSeconds;
                                serverDbContextOptionsBuilder.CommandTimeout(minutes);
                                serverDbContextOptionsBuilder.EnableRetryOnFailure();
                            });
                    });
                    //services.AddTransient<XContext>();
                    //services.AddTransient<XContext>();
                    services.AddScoped<XContext>();

                    //workers
                    services.AddHostedService<Worker1>();
                    services.AddHostedService<Worker2>();
                });
    }

工人:

     public class Worker1: BackgroundService
        {
            private readonly ILogger<Worker1> _logger;
    
            private readonly IConfiguration _configuration;
    
            private readonly TookoContext _uow;
    
             
    
            public Worker1(ILogger<Worker1> logger,IConfiguration configuration,XContext uow)
            {
                _logger = logger;
                _configuration = configuration;
                _uow = uow;
            }
   // ...
}

我有这个错误

某些服务无法构建(验证时出错> 服务描述符 ServiceType: Microsoft.Extensions.Hosting.IHostedService 生命周期:单例 实施类型:Worker1':无法使用范围服务 'XContext' 来自单身

解决方法

您需要将 IServiceProvider 注入托管服务,然后在需要 XContext 时:

using (var scope = _serviceProvider.CreateScope())
{
    var context = scope.GetRequiredService<XContext>();
    // ...
}

DBContext 旨在是短暂的,所以不要试图在您的服务启动时创建一个并在服务的生命周期内保留它。相反,您应该在需要时创建、简要使用,然后处理它们。

在上面的例子中,作用域将处理上下文;你不需要 - 也不应该 - 自己做。