thepirat000 / Audit.NET

An extensible framework to audit executing operations in .NET and .NET Core.
MIT License
2.27k stars 323 forks source link

Audit.NET and Autofac #338

Closed thekokii closed 3 years ago

thekokii commented 3 years ago

Sorry for this is being a question instead of an actual issue, but I don't really find a proper description for what I try to achieve which I suppose should be a simple usecase. I use Autofac in my project, and I would like to use a (scoped) service which I register in my container when I configure with .AuditEntityAction. It's achievable, but it seems I can only resolve my desired service from a different scope I suppose.

Thanks in advance!

thepirat000 commented 3 years ago

Could you add some code to help understanding the problem

thekokii commented 3 years ago
Configuration
                .Setup()
                .UseEntityFramework(_ => _
                    .AuditTypeMapper(t => typeof(AuditLog))
                    .AuditEntityAction<AuditLog>((ev, entry, entity) =>
                    {
                        entity.CustomProperty = serviceProvider.GetService<MyLifeTimeScopedService>().MyProperty;
                    })

What is my problem that I cannot resolve the wanted service as it lives in a different scope, I would like to ask the service from my own configured DI which seems not to be available in the startup phase where the audit has its setup.

thepirat000 commented 3 years ago

That should work.

The code inside the AuditEntityAction is not executed on the startup, but when an audit is about to be saved.

You could also use Custom Action, for example:

Configuration.AddCustomAction(ActionType.OnScopeCreated, scope =>
{
    scope.SetCustomField("CustomProperty", serviceProvider.GetService<MyLifeTimeScopedService>().MyProperty);
});

Configuration.Setup()
    .UseEntityFramework(_ => _
        .AuditTypeMapper(t => typeof(AuditLog))
        .AuditEntityAction<AuditLog>((ev, entry, entity) =>
        {
            entity.CustomProperty = ev.CustomFields["CustomProperty"];
        })
thekokii commented 3 years ago

At the beginning of an http request the service gets resolved as expected among our api call through various other services and "reinjection". What is the problem is that at the ~end of the request when data changes happen and the AuditEntityAction gets triggered, the scope seems not to be connected here, instead what was used during the whole call scope, a new instance gets initiated. What is my question basically that this way it should work and we should dig in our DI or am I missing something and there is some special way where we could attach our container to the audit registration? But as I read your words it seems to be the first.

thepirat000 commented 3 years ago

Just to clarify, Audit.NET configuration is stored on static properties on class Audit.Core.Configuration. The UseXXX() methods like Audit.Core.Configuration.Setup().UseEntityFramework() just set the static data provider property Audit.Core.Configuration.DataProvider.