EFCore 在 DbCommandInterceptor 中注入服务

RBa*_*iak 6 c# entity-framework-core

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

我需要在拦截器中注入一个范围服务,这样这是不可能的。

有没有办法将作用域数据库拦截器添加到 a DbContext

services.AddDbContext<DatabaseContext>(options =>
    options.UseSqlServer(
        Configuration.GetConnectionString(...)
    .AddInterceptors(new DatabaseLogIntgerceptor()); 
Run Code Online (Sandbox Code Playgroud)

Iva*_*oev 9

该方法接收一个实例,使拦截器成为单例。

实际上它不是单例,而是范围的。

AddDbContext几个重载,所有重载都有 2 个可选参数

contextLifetimeDbContext在容器中 注册服务的生命周期。

optionsLifetimeDbContextOptions在容器中 注册服务的生命周期。

两者都默认为ServiceLifetime.Scoped. optionsLifetime还控制调用选项配置操作的范围。

所以默认情况下

.AddInterceptors(new DatabaseLogIntgerceptor())
Run Code Online (Sandbox Code Playgroud)

将在每个作用域中调用,从而可以在其中注入作用域服务。

至于如何做到这一点,您必须使用AddDbContext重载与操作接收IServiceProvider并解析其中的服务(或拦截器),例如

services.AddDbContext<DatabaseContext>((sp, options) => options
    .UseSqlServer(
        Configuration.GetConnectionString(...)
    )
    .AddInterceptors(
        sp.GetRequiredService<DatabaseLogInterceptor>()
    )
);
Run Code Online (Sandbox Code Playgroud)