EFCore injecting services in DbCommandInterceptor

Viewed 587

As I can see from the database interceptors I found for EF Core, they must be registered in Startup.cs using the AddInterceptors method. This method receives an instance, making the interceptor a singleton.

I need to inject a scoped service in the interceptor and this way it's not possible.

Is there any way to add scoped db interceptors to a DbContext?

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

This method receives an instance, making the interceptor a singleton.

Actually it isn't singleton, but scoped.

AddDbContext has several overloads, all having 2 optional arguments

contextLifetime The lifetime with which to register the DbContext service in the container.

optionsLifetime The lifetime with which to register the DbContextOptions service in the container.

both defaulting to ServiceLifetime.Scoped. optionsLifetime also controls the scope of calling the options configuration action.

So by default

.AddInterceptors(new DatabaseLogIntgerceptor())

will be called per each scope, thus making possible to inject scoped service in it.

As of how to do that, you have to use the AddDbContext overloads with action receiving IServiceProvider and resolve the services (or the inteceptor) from it, for instance

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