如何在 asp.net 核心中部署作用域服务之前执行方法?

How to execute method before scoped service is disposed in asp.net core?

我有一个自定义中间件,其目的是订阅 EF Core dbcontext 事件并跟踪实体发生的更改。 中间件在每个请求开始时将我的 InteractionService 实例化为范围实例。这就是我的中间件的样子:

public static IApplicationBuilder UseDbContextActivityTracker<TContext>(this IApplicationBuilder app)
    where TContext : DbContext
{
    app.Use(async (context, next) =>
    {
        var service = context.RequestServices.GetRequiredService<InteractionService<TContext>>();
        await next.Invoke();
        service.PersistLogs();
    });

    return app;
}

这就是我在 Startup 的 Confiure 方法中使用中间件的方式 class:

options.UseDbContextActivityTracker<ApplicationDbContext>();

在我的 InteractionService 的构造函数中,我通过 DI 获得了对 dbcontext 的引用并订阅了事件:

public InteractionService(TContext context)
{
    this.context = context;
    this.context.ChangeTracker.StateChanged += ChangeTracker_StateChanged;
}

在请求期间监听 dbContext 发生的事件时,我将相关信息存储到我自己的实体中,并且效果很好。但是,在请求结束时,我想将更改保存到数据库中。我尝试使我的 InteractionService class IDisposable 并在 Dispose 方法中,我正在调用另一个 DbContext 来保存我的实体。正如预期的那样,我得到了错误 "Connection already closed"。 请求完成后将我的实体保存到数据库的正确位置是什么?

@Panagiotis Kanavos 为我指出了正确的方向。我的问题是如何获得范围适当的 DbContext 来写入更改。在我的 InteractionService 中,我没有通过构造函数注入 DbContext,而是使用 serviceProvider 手动创建它。我改变了这个:

public CampusAxessInteractionStore(MyDbContext context)
{
    this.context = context;
}

对此:

public CampusAxessInteractionStore(IServiceProvider serviceProvider)
{
    var scopeResolver = serviceProvider.GetRequiredService<IServiceScopeFactory>().CreateScope();
    this.context = scopeResolver.ServiceProvider.GetRequiredService<CampusAxessDbContext>();
}

现在可以保存了。 虽然我仍然不确定这是否是正确的方法。如果有人可以告诉我应该如何正确完成此操作,请这样做,我将删除我的答案并将您的答案标记为正确。