[英]Proper way to inject a dependency into DBContext
我正在尝试使用 DDD 和微服务方法创建一个项目,并且我有一个关于将域事件发送到另一个服务的小问题。 我使用 EF Core 进行数据库通信,使用 MassTransit 发送事件。
现在我在我的 DBConetxt 中有一个重写的 SaveChangesAsync 方法,我通过我在 Startup.cs 中使用 MassTransit 创建的总线发送域事件。
数据库上下文:
private readonly IBus _bus;
public StudentsDbContext(DbContextOptions options, IBus bus) : base(options)
{
_bus = bus;
}
...
public override async Task<int> SaveChangesAsync(CancellationToken cancellationToken = new CancellationToken())
{
var aggregates = ChangeTracker.Entries<IAggregateRoot>().ToList();
foreach (var aggregate in aggregates)
{
foreach (var domainEvent in aggregate.Entity.DomainEvents)
{
await _bus.Publish(domainEvent, domainEvent.GetType(), cancellationToken);
}
aggregate.Entity.ClearEvents();
}
return await base.SaveChangesAsync(cancellationToken);
}
如您所见,我需要将IBus
注入 DbContext 构造函数,因此我遇到了一些麻烦。 例如,由于我的构造函数,我无法使用AddDbContext
方法在 Startup.cs 文件中注册我的 DbContext,所以我需要这样做:
services.AddSingleton<IBus>(bus);
services.AddTransient<StudentsDbContext>(provider =>
{
var options = new DbContextOptionsBuilder()
.UseSqlServer(Configuration.GetConnectionString("Default"))
.Options;
return new StudentsDbContext(options, provider.GetService<IBus>());
});
因此,我在迁移方面遇到了问题。
Unable to create an object of type 'StudentsDbContext'. For the different patterns supported at design time, see https://go.microsoft.com/fwlink/?linkid=851728
而且我还想使用像 AddDbContextPool 这样的池化AddDbContextPool
。
所以我有两个问题:
您做错了。我认为您必须将代码更正为:
public StudentsDbContext(DbContextOptions<OrderingContext> options, IBus bus) : base(options)
{
_bus = bus ?? throw new ArgumentNullException(nameof(bus));
}
在你的启动中:
services.AddDbContext<StudentsDbContext>(options =>
{
options.UseSqlServer(Configuration["ConnectionString"]);
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.