Callback on SaveChanges in EFCore?

asp.net-core autofac c# dbcontext entity-framework-core

Question

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
1
1/29/2019 5:13:49 AM

Popular Answer

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

0
1/29/2019 2:01:40 PM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow