gpt4 book ai didi

c# - 在托管服务中访问上下文

转载 作者:行者123 更新时间:2023-12-03 23:36:27 25 4
gpt4 key购买 nike

我需要从此类访问上下文,以便可以检查数据库中的一些数据,但我不知道如何将其传输到以下服务:

internal class TimedHostedService : IHostedService, IDisposable
{
private readonly ILogger _logger;
private Timer _timer;



public TimedHostedService(ILogger<TimedHostedService> logger) //context ?
{

_logger = logger;


}

public Task StartAsync(CancellationToken cancellationToken)
{
_logger.LogInformation("Timed Background Service is starting.");

_timer = new Timer(DoWork, null, TimeSpan.Zero,
TimeSpan.FromSeconds(60));

return Task.CompletedTask;
}

private void DoWork(object state)
{
_logger.LogInformation("Atualização automática");


}

public Task StopAsync(CancellationToken cancellationToken)
{
_logger.LogInformation("Timed Background Service is stopping.");

_timer?.Change(Timeout.Infinite, 0);

return Task.CompletedTask;
}

public void Dispose()
{
_timer?.Dispose();
}
}

启动文件:
namespace Products
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}

public IConfiguration Configuration { get; }

// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{

services.AddCors(o => o.AddPolicy("AllowAllOrigins", builder =>
{
builder.AllowAnyMethod()
.AllowAnyHeader()
.AllowAnyOrigin();
}));

services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);

services.AddDbContext<Context>(options =>
options.UseSqlServer(Configuration.GetConnectionString("LaprDB")));
services.AddDbContext<ContextUsers>(options =>
options.UseSqlServer(Configuration.GetConnectionString("MyDbConnection")));

services.AddHostedService<TimedHostedService>();

}

// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseHsts();
}

app.UseCors("AllowAllOrigins");
app.UseHttpsRedirection();
app.UseMvc();

}
}
}

我用范围工厂搜索了一些解决方案,但我无法理解其中的任何一个。有人可以解释我如何将上下文转移到 TimedHostedService 吗?
如果您需要更多信息,请告诉我。

最佳答案

托管服务是一个单例,这意味着该类的一个实例在应用程序的生命周期内只存在。

上下文是有范围的,这意味着它被设计为具有非常短的生命周期(仅适用于特定的“范围”,例如单个 HTTP 请求)。它不擅长无限期地保持事件状态(例如,涉及数据库连接,您不能保证在应用程序的生命周期内保持打开状态)。

如果您将 Context 注入(inject)另一个类,则 Context 将在该类的实例的生命周期内存在。对于单例类,这就是应用程序的生命。所以这就是为什么你会得到你所做的异常(exception)。 .NET Core 告诉你:“这不会像你认为的那样工作”

解决方案在这里:https://stackoverflow.com/a/48368934/1202807

简而言之,注入(inject)一个 IServiceScopeFactory ,这使您可以在需要时要求 DI 引擎为您提供一个作用域类,然后由您决定只在需要时保留它。

private readonly IServiceScopeFactory _scopeFactory;

public TimedHostedService(ILogger<TimedHostedService> logger, IServiceScopeFactory scopeFactory)
{
_logger = logger;
_scopeFactory = scopeFactory;
}

然后你得到你的上下文是这样的:
using (var scope = scopeFactory.CreateScope())
{
var context = scope.ServiceProvider.GetRequiredService<Context>();
//do what you need
}//scope (and context) gets destroyed here

旧答案(这里是错误的,但适用于其他类型的类):

只需将其放入您的构造函数中,它就会被 dependency injection 注入(inject):
public TimedHostedService(ILogger<TimedHostedService> logger, Context context)
{
_logger = logger;
_context = context;
}

这是 services.AddDbContext()使它们可用于依赖注入(inject)的行。只需选择您想要的类型,因为您已经定义了两个:
services.AddDbContext<Context>(options =>
options.UseSqlServer(Configuration.GetConnectionString("LaprDB")));
services.AddDbContext<ContextUsers>(options =>
options.UseSqlServer(Configuration.GetConnectionString("MyDbConnection")));

关于c# - 在托管服务中访问上下文,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53843503/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com