gpt4 book ai didi

c# - 依赖注入(inject)的 DbContext 始终为 null

转载 作者:行者123 更新时间:2023-12-02 07:07:20 25 4
gpt4 key购买 nike

我在多个 ASP.NET(Core)应用程序中使用了 DI,其中 DbContext 被注入(inject)到 Controller 构造函数中,并且在向 Controller 发出第一个请求时,运行构造函数并注入(inject)依赖项。

我现在正在处理一个连接到 Azure 消息总线的 Web API 项目,处理和保存来自总线的数据,并为数据提供 API 终结点。处理和保存来自 Azure 消息总线的消息的类是 QueueProcessor .

我需要保留项目启动时的数据,这意味着我需要项目运行时的 DbContext 实例,而不是通过 API 端点查询数据时的 DbContext 实例。因此, QueueProcessor 的构造函数永远不会隐式调用,如果我想手动执行此操作,我需要 MyDbContext 的预先存在的实例传递给它。

我已经研究这个问题几天了,尝试了一些手动模式,但我遇到了并发问题,整个项目目前感觉就像是黑客攻击。

The closest question I've come across is this, which despite specifying non-controllers, the accepted answer requires a controller for the dependency to be injected.

这就是我目前正在做的事情:

    public void ConfigureServices(IServiceCollection services)
{
services.AddHangfire(x => x.UseSqlServerStorage(Configuration.GetConnectionString("DefaultConnection")));

services.AddDbContextPool<MyDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("default")));

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

然后我必须创建我的 QueueProcessor 的新实例并使用var context = new MyDbContext()在构造函数内部。这会导致并发问题并完全否定 DI .

如果我想注入(inject)MyDbContext像我已经做过数百次一样,使用 DI 创建类的实例来运行 QueueProcessor 内的进程意味着我必须传递 MyDbContext 的实例给我自己的构造函数。 VS 在设计时标记了这一点。

我曾经尝试通过以下方式尽可能地搞砸这个:

services.AddTransient(x => new QueueProcessor(x.GetService<MyDbContext>(), Configuration.GetConnectionString("MessageBus")));

我正在寻找一种更干净的方式来实现:

  • 调用 QueueProcessor 中的方法从项目启动时处理 Azure 消息总线消息。
  • 在处理消息之前,我应该有一个 MyDbContext 的实例化实例当消息被处理时我可以用它来保存消息。
  • 不必使用Controller正确设置 DI。

有没有办法实现这一目标,或者我完全错过了这里的目标?

最佳答案

一个可行的解决方案,不确定它是否是最佳模式:

  1. Startup.cs机会ConfigureServices返回IServiceProvider而不是void .
  2. 使用: var serviceProvider = services.BuildServiceProvider(); 构建 serviceProvider
  3. 获取 MyDbContext 实例:var context = serviceProvider.GetRequiredService<MyDbContext>();
  4. 创建 QueueProcessor 的实例并通过 context到构造函数和调用方法以开始处理消息。
  5. 来自 ConfigureServices ,返回新的 serviceProvider .

完整代码块:

    public IServiceProvider ConfigureServices(IServiceCollection services)
{
services.AddDbContext<MyDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("...")));

var serviceProvider = services.BuildServiceProvider();

var localMyDbContext = serviceProvider.GetRequiredService<MyDbContext>();

Processor = new QueueProcessor(localDbContext, Configuration.GetConnectionString("Other"));
Processor.RunAsync().GetAwaiter().GetResult();

return serviceProvider;
}

关于c# - 依赖注入(inject)的 DbContext 始终为 null,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53517321/

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