EFCore在DbCommandInterceptor中注入服务

4

从我找到的EF Core数据库拦截器中可以看出,它们必须使用AddInterceptors方法在Startup.cs中注册。这个方法接收一个实例,使拦截器成为单例。

我需要在拦截器中注入范围服务,但这种方式是不可能的。

是否有一种方法可以将作用域的db拦截器添加到DbContext中?

services.AddDbContext<DatabaseContext>(options =>
    options.UseSqlServer(
        Configuration.GetConnectionString(...)
    .AddInterceptors(new DatabaseLogIntgerceptor()); 
1个回答

8
这个方法接收一个实例,将拦截器作为单例模式。 其实它不是单例模式,而是作用域模式。 AddDbContext多个重载方法,都有两个可选参数。 contextLifetime 注册在容器中的 DbContext 服务的生命周期。 optionsLifetime 注册在容器中的 DbContextOptions 服务的生命周期。
这两个参数默认值均为 ServiceLifetime.Scoped。其中,optionsLifetime 还控制调用选项配置操作的范围。
所以,默认情况下:
.AddInterceptors(new DatabaseLogIntgerceptor())

每个作用域将调用一次,因此可以在其中注入限定作用域的服务。

关于如何实现此功能,需要使用接收IServiceProvider的操作的AddDbContext重载,并从中解析服务(或拦截器),例如:

services.AddDbContext<DatabaseContext>((sp, options) => options
    .UseSqlServer(
        Configuration.GetConnectionString(...)
    )
    .AddInterceptors(
        sp.GetRequiredService<DatabaseLogInterceptor>()
    )
);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接