首页 > 解决方案 > DbCommandInterceptor 中的 EFCore 注入服务

问题描述

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

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

有什么方法可以将作用域数据库拦截器添加到一个DbContext

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

标签: c#entity-framework-core

解决方案


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

实际上它不是单例,而是作用域。

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

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

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

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

所以默认情况下

.AddInterceptors(new DatabaseLogIntgerceptor())

将在每个范围内调用,从而可以在其中注入范围服务。

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

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

推荐阅读