问题
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