如何在 DbCommandInterceptor 中使用服务或 DbContext?
How to use a Service or DbContext inside DbCommandInterceptor?
我有一个应用程序可以将数据从 MySql 数据库同步到 SQL 服务器数据库。
考虑这两个 DbContext 服务:
services.AddDbContext<SqlServerContext>(options => options
.UseSqlServer(Configuration.GetConnectionString("SqlServer")));
services.AddDbContext<MySqlContext>(options => options
.UseMySql(Configuration.GetConnectionString("MySql"))
.AddInterceptors(new MySqlInterceptor()));
在MySqlInterceptor()
;我想inject/resolve/use一个Service
甚至SqlServerContext
,为了得到配置修改CommandText
。
有什么想法吗?
根据您要覆盖的方法,您将在方法定义中收到 CommandEventData
对象,其中 DbContext
为 属性。
关于服务和配置,您可以在注册前配置拦截器。
而不是这个:
services.AddDbContext<MySqlContext>(options => options
.UseMySql(Configuration.GetConnectionString("MySql"))
.AddInterceptors(new MySqlInterceptor()));
你可以做到
var interceptor = new MySqlInterceptor(service1, service2 ... etc);
services.AddDbContext<MySqlContext>(options => options
.UseMySql(Configuration.GetConnectionString("MySql"))
.AddInterceptors(interceptor))
如何解析拦截器实例:
如果您需要自动连接拦截器的依赖项,您可以执行以下操作
services.AddTransient<Service1>();
services.AddTransient<Service2>();
services.AddTransient<MySqlInterceptor>();
// resolve the instalce of the interceptor
var serviceProvider = services.BuildServiceProvider();
var interceptor = serviceProvider.GetService<MySqlInterceptor>();
// configure mysql context and interceptor
services.AddDbContext<MySqlContext>(options => options
.UseMySql(Configuration.GetConnectionString("MySql"))
.AddInterceptors(interceptor))
正如@vasil 在他的 中提到的:
Depending on the method you are going to override, you will receive
CommandEventData object in the method definition which has the
DbContext
as property.
但就我而言,我想解析使用 另一个 DbContext 的服务,这被证明很麻烦;所以我最终将我需要的设置放入 appsettings.json,并使用 IConfiguration
服务获取设置值并将其发送到拦截器构造函数:
services.AddDbContext<MySqlContext>(options => options
.UseMySql(Configuration.GetConnectionString("MySql"))
.AddInterceptors(new MySqlInterceptor(Configuration["SettingValue"])));
注意:如果您找到了这个答案,并且正在寻找一种方法来解决 ConfigureService
方法中的服务,而无需调用 BuildServiceProvider
,就像大卫·福勒 (David Fowler) 在 Github issue 上说的那样,您会:
building the container while trying to build it
你最终会得到:
2 containers and one of them will never be disposed.
您可以按照 Nkosi 在他 中的建议进行操作:
services.AddScoped<IService>(x =>
new Service(x.GetRequiredService<IOtherService>(),
x.GetRequiredService<IAnotherOne>(),
""));
我有一个应用程序可以将数据从 MySql 数据库同步到 SQL 服务器数据库。
考虑这两个 DbContext 服务:
services.AddDbContext<SqlServerContext>(options => options
.UseSqlServer(Configuration.GetConnectionString("SqlServer")));
services.AddDbContext<MySqlContext>(options => options
.UseMySql(Configuration.GetConnectionString("MySql"))
.AddInterceptors(new MySqlInterceptor()));
在MySqlInterceptor()
;我想inject/resolve/use一个Service
甚至SqlServerContext
,为了得到配置修改CommandText
。
有什么想法吗?
根据您要覆盖的方法,您将在方法定义中收到 CommandEventData
对象,其中 DbContext
为 属性。
关于服务和配置,您可以在注册前配置拦截器。
而不是这个:
services.AddDbContext<MySqlContext>(options => options
.UseMySql(Configuration.GetConnectionString("MySql"))
.AddInterceptors(new MySqlInterceptor()));
你可以做到
var interceptor = new MySqlInterceptor(service1, service2 ... etc);
services.AddDbContext<MySqlContext>(options => options
.UseMySql(Configuration.GetConnectionString("MySql"))
.AddInterceptors(interceptor))
如何解析拦截器实例:
如果您需要自动连接拦截器的依赖项,您可以执行以下操作
services.AddTransient<Service1>();
services.AddTransient<Service2>();
services.AddTransient<MySqlInterceptor>();
// resolve the instalce of the interceptor
var serviceProvider = services.BuildServiceProvider();
var interceptor = serviceProvider.GetService<MySqlInterceptor>();
// configure mysql context and interceptor
services.AddDbContext<MySqlContext>(options => options
.UseMySql(Configuration.GetConnectionString("MySql"))
.AddInterceptors(interceptor))
正如@vasil 在他的
Depending on the method you are going to override, you will receive CommandEventData object in the method definition which has the
DbContext
as property.
但就我而言,我想解析使用 另一个 DbContext 的服务,这被证明很麻烦;所以我最终将我需要的设置放入 appsettings.json,并使用 IConfiguration
服务获取设置值并将其发送到拦截器构造函数:
services.AddDbContext<MySqlContext>(options => options
.UseMySql(Configuration.GetConnectionString("MySql"))
.AddInterceptors(new MySqlInterceptor(Configuration["SettingValue"])));
注意:如果您找到了这个答案,并且正在寻找一种方法来解决 ConfigureService
方法中的服务,而无需调用 BuildServiceProvider
,就像大卫·福勒 (David Fowler) 在 Github issue 上说的那样,您会:
building the container while trying to build it
你最终会得到:
2 containers and one of them will never be disposed.
您可以按照 Nkosi 在他
services.AddScoped<IService>(x =>
new Service(x.GetRequiredService<IOtherService>(),
x.GetRequiredService<IAnotherOne>(),
""));