问题
I'm trying to do something like in my DbContext
:
public System.Action<IEnumerable<EntityEntry>> OnSave;
public override int SaveChanges() {
if(OnSave != null)
OnSave(ChangeTracker.Entries());
return base.SaveChanges();
}
Then DI (AutoFac) the DbContext
into another class which can hook into the 'OnSave' function.
I'm looking for a single source of truth when this happens.
I don't think this will work or be reliable when DbContext
is injected into multiple places since I'm pretty sure we end up with multiple instances of DbContext
for every place it's injected into.
回答1:
Sounds like you want your OnSave
method to be a singleton (the same method used in all instances of your DbContext
).
One way to solve this is to move your Action
to a new class:
public class MySaveEventHandler {
public System.Action<IEnumerable<EntityEntry>> OnSave;
}
Then add it as a singleton in your Startup.cs to make it available for dependency injection:
services.AddSingleton<MySaveEventHandler>();
Then change you DbContext
constructor to accept that via DI and use that in your SaveChanges
method:
MySaveEventHandler _mySaveEventHandler;
public MyDbContext(DbContextOptions<MyDbContext> options, MySaveEventHandler mySaveEventHandler) : base(options) {
_mySaveEventHandler = mySaveEventHandler;
}
public override int SaveChanges() {
if(_mySaveEventHandler.OnSave != null)
_mySaveEventHandler.OnSave(ChangeTracker.Entries());
return base.SaveChanges();
}
To set the OnSave
method, you simply get your single MySaveEventHandler
instance via DI and set it. Then every instance of your DbContext
will use it.
Side note: You could use an event instead of a delegate. Really I don't think it'll make much of a functional difference, but there's some interesting reading about it here: https://docs.microsoft.com/en-us/dotnet/csharp/distinguish-delegates-events
来源:https://stackoverflow.com/questions/54412585/callback-on-savechanges-in-efcore