【发布时间】:2019-04-30 05:39:05
【问题描述】:
我在多个 ASP.NET (Core) 应用程序中使用 DI,其中 DbContext 被注入到控制器构造函数中,并且在对控制器的第一次请求时,构造函数运行并注入依赖项。
我现在正在处理一个连接到 Azure 消息总线的 Web API 项目,处理和保存来自总线的数据,并为数据提供 API 端点。处理和持久化来自 Azure 消息总线的消息的类是 QueueProcessor。
我需要从项目开始时保存数据,这意味着我需要从项目运行时开始的 DbContext 实例,而不是通过 API 端点查询数据时。因此,QueueProcessor 的构造函数永远不会被隐式调用,如果我想手动这样做,我需要一个预先存在的MyDbContext 实例来传递给它。
我已经研究了几天,尝试了一些手动模式,但我遇到了并发问题,整个项目现在感觉就像一个 hack。
这是我目前正在做的:
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()。这会导致并发问题并完全否定@987654328@。
如果我想用 DI 注入 MyDbContext,就像我已经做过数百次一样,创建类的实例以在 QueueProcessor 内运行进程意味着我必须将 MyDbContext 的实例传递给构造函数我。 VS 在设计时将其标记出来。
我曾经尝试过尽可能地搞砸这个:
services.AddTransient(x => new QueueProcessor(x.GetService<MyDbContext>(), Configuration.GetConnectionString("MessageBus")));
我正在寻找一种更清洁的实现方式:
- 调用
QueueProcessor中的方法以从项目开始处理 Azure 消息总线消息。 - 在处理消息之前,我应该有一个
MyDbContext的实例化实例,我可以使用它在消息被处理时持久化它们。 - 不必使用
Controller来正确设置 DI。
有没有办法实现这一点,还是我完全错过了这里的标记?
【问题讨论】:
标签: c# entity-framework azure dependency-injection async-await