koenbeuk / EntityFrameworkCore.Triggered

Triggers for EFCore. Respond to changes in your DbContext before and after they are committed to the database.
MIT License
554 stars 29 forks source link

Struggle finding triggers, then triggers not firing #194

Closed bzbetty closed 5 months ago

bzbetty commented 5 months ago

Using AddTriggeredDbContextI noticed that it calls UseTriggers itself, however I want to register types in a different assembly.

So i tried the following

            builder.AddTriggeredDbContext<Context>((serviceProvider, opt) =>
            {
                opt.UseSqlServer(config["ConnectionString"], x =>
                {

                })
                .UseTriggers(triggerOptions =>
                {
                    triggerOptions.AddAssemblyTriggers(typeof(Context).Assembly);
                })
                .EnableSensitiveDataLogging();              
            });

but the triggers don't seem to be executed. I'm wondering if it's because the UseTriggers call inside AddTriggeredDbContext is replacing them?

bzbetty commented 5 months ago

hmm seems to be used that way in the blazor example, so maybe i'm totally wrong.

https://github.com/koenbeuk/EntityFrameworkCore.Triggered/blob/7f3cae20e106d5eaeac3544c17010dce9cc91d02/samples/4%20-%20BlazorTests/Startup.cs#L27

bzbetty commented 5 months ago

tried using registration from https://github.com/koenbeuk/EntityFrameworkCore.Triggered/wiki/Trigger-registration

it finds and registers the trigger with DI container, but a breakpoint in the constructor of the context, looking into the options then extensions I see zero triggers on the extension.

bzbetty commented 5 months ago

weirdly only happening in the azure functions project, the unit test one works fine.

bzbetty commented 5 months ago

using AddTriggeredDbContextFactory + https://github.com/koenbeuk/EntityFrameworkCore.Triggered/wiki/Trigger-registration ended up working for me. Couldn't get it working with AddAssemblyTriggers.

            RegisterAssemblyTriggers(builder, typeof(IBeforeSaveTrigger<>));
            RegisterAssemblyTriggers(builder, typeof(IAfterSaveTrigger<>));
            RegisterAssemblyTriggers(builder, typeof(IAfterSaveFailedTrigger<>));

            builder.AddTriggeredDbContextFactory<ESPContext>((opt) =>
            {
                var config = serviceProvider.GetService<IConfiguration>();
                opt.UseSqlServer(config["ConnectionString"], x =>
                {                  
                })
                .UseTriggers()
                .EnableSensitiveDataLogging();
            });
bzbetty commented 5 months ago

Edit - actually was looking at the wrong property (was looking at trigger types instead of triggers) there's still no triggers being discovered.

bzbetty commented 5 months ago

ok, have triggers discovered now using

            builder.AddTriggeredDbContextFactory<ESPContext>((serviceProvider, opt) =>

with

                .UseTriggers(triggerOptions => triggerOptions.AddAssemblyTriggers(typeof(ESPContext).Assembly))

but i am referencing the code directly with some tweaks rather than the nuget package.

which led to finding #196

weirdly now the TriggerSessionSaveChangesInterceptor doesn't seem to be triggered on savechanges (although still does in the unit tests).

Starting to think it's somethign weird i've done with the service providers.

On a side note I'm not sure I'm a fan of the async change in v4 - I get why (deadlocks) but it's certainly a footgun as async triggers don't get run on SaveChanges() which people may not realise they're calling.

bzbetty commented 5 months ago

got it working.

I had to AddInterceptor manually but make sure it was done after the interceptor existed in the DI container.

            builder.AddTransient<TriggerSessionSaveChangesInterceptor>();

            builder.AddTriggeredDbContextFactory<ESPContext>((serviceProvider, opt) =>
            {
                var config = serviceProvider.GetService<IConfiguration>();
                var triggerInterceptor = serviceProvider.GetService<TriggerSessionSaveChangesInterceptor>();

                opt.UseSqlServer(config["ConnectionString"], x =>
                {
                })
                .UseTriggers(triggerOptions => triggerOptions.AddAssemblyTriggers(typeof(ESPContext).Assembly))
                .AddInterceptors(triggerInterceptor)
                .EnableSensitiveDataLogging();
            });     
bzbetty commented 5 months ago

not 100% sure but it seems that AddTriggeredDbContextFactory is somehow triggered much earlier than AddDbContextFactory was. So I think my issue was around stuff not being registered in the DI container early enough.