dotnet / efcore

EF Core is a modern object-database mapper for .NET. It supports LINQ queries, change tracking, updates, and schema migrations.
https://docs.microsoft.com/ef/
MIT License
13.6k stars 3.14k forks source link

Add an interceptor to an existing DbContext instance #20273

Open Giorgi opened 4 years ago

Giorgi commented 4 years ago

I know that interceptors can be added when creating the model using DbContextOptionsBuilder.AddInterceptors method but is there a way to add an interceptor instance on an existing DbContext instance?

This can be useful for third party library developers which want to add interception capability to the existing DbContext instance.

ajcvickers commented 4 years ago

Putting this on the backlog as something that would be useful. However, traditional events may be more appropriate--see #626.

Giorgi commented 4 years ago

So this means that there is no way to do it in the 3.1 version right ?

ajcvickers commented 4 years ago

@Giorgi Correct.

Giorgi commented 4 years ago

There is also no way to get the command text and parameters from IQueryable<> neither.

ajcvickers commented 4 years ago

@Giorgi See #19358

Giorgi commented 4 years ago

Yes, looks like I will have to wait until EF Core 5

jamiewinder commented 1 year ago

Since this is quite an old issue, is there a way to do this currently? In my case, I'm hoping to be able to attach a connection interceptor to an existing DbContext (or through a IDbContextFactory if more appropriate) with an interceptor that performs tenancy isolation. Basically so I can implement a DbContext CreateTenantContext(Guid tenantId) factory method. As far as I can tell, my only option at the moment is to create a DbContext, force the connection to open (so it stays open), and then run a command on it.

ajcvickers commented 1 year ago

@jamiewinder With a context factory, you control creating the instance of the context, so you can add whatever interceptors you want there. There isn't a way to add interceptors after the context has been initialized; this issue is tracking that.

jamiewinder commented 1 year ago

@ajcvickers Thanks. Just to make sure I'm understanding correctly, I think I'm correct in saying that currently I can only control which interceptors are added when the factory is created rather than when I ask if for a context to be created? i.e. I can't do anything like this:

private readonly IDbContextFactory<MyContext> _contextFactory;

public MyContext CreateTenantContext(Guid tenantId)
{
   var setTenancyInterceptor = new SetTenancyInterceptor(tenantId);
   return _contextFactory.CreateDbContextWithInterceptors(setTenancyInterceptor);
}

(obviously CreateDbContextWithInterceptors isn't a thing, just an example)

ajcvickers commented 1 year ago

You can do whatever you want in your implementation of IDbContextFactory.

jamiewinder commented 1 year ago

It seems I grossly overestimated what was involved in creating a IDbContextFactory! That's perfect, thanks for the pointers!