c# - DbCommandInterceptor 中的 EFCore 注入服务
问题描述
从我为 EF Core 找到的数据库拦截器中可以看出,它们必须Startup.cs
使用该AddInterceptors
方法注册。此方法接收一个实例,使拦截器成为单例。
我需要在拦截器中注入一个作用域服务,这样是不可能的。
有什么方法可以将作用域数据库拦截器添加到一个DbContext
?
services.AddDbContext<DatabaseContext>(options =>
options.UseSqlServer(
Configuration.GetConnectionString(...)
.AddInterceptors(new DatabaseLogIntgerceptor());
解决方案
此方法接收一个实例,使拦截器成为单例。
实际上它不是单例,而是作用域。
AddDbContext
有几个重载,都有 2 个可选参数
contextLifetime
DbContext
在容器中 注册服务的生命周期。optionsLifetime
DbContextOptions
在容器中 注册服务的生命周期。
两者都默认为ServiceLifetime.Scoped
. optionsLifetime
还控制调用选项配置操作的范围。
所以默认情况下
.AddInterceptors(new DatabaseLogIntgerceptor())
将在每个范围内调用,从而可以在其中注入范围服务。
至于如何做到这一点,您必须使用AddDbContext
带有动作接收的重载并IServiceProvider
从中解析服务(或拦截器),例如
services.AddDbContext<DatabaseContext>((sp, options) => options
.UseSqlServer(
Configuration.GetConnectionString(...)
)
.AddInterceptors(
sp.GetRequiredService<DatabaseLogInterceptor>()
)
);
推荐阅读
- ios - 如何在 Swift 3 中检查当前 ViewController?
- c++ - 在 C++ 中给出错误输出的阶乘问题
- android - Android Studio 和 Google Maps API 片段崩溃
- grammar - 从语法中导出正则表达式
- c - 我们可以在 getopt 中添加更多选项吗?
- r - 在 Windows 机器上的 R 控制台中安装 rJava 时出错
- winapi - 以非提升方式运行时,为提升的应用程序调用 LowLevelKeyboardProc
- javascript - 在 Node/raw ES6 中,我如何从父类发出事件并从它们各自的构造函数触发子类中的事件?
- spring - spring boot 2 + feign + eureka 客户端不会将服务名称解析为 URL
- variables - 如何检查 Kotlin 变量的类型