I have the following Setup
Audit.Core.Configuration.Setup() // Triggered on a database save.
.UseEntityFramework(ef => ef
.AuditTypeExplicitMapper(m => m
.Map<Item, AuditLog>()
.AuditEntityAction<AuditLog>((evt, entry, auditEntity) =>
{
auditEntity.AuditData = entry.ToJson();
auditEntity.AuditDate = DateTime.UtcNow;
auditEntity.CallingMethod = "Calling Method"; <-- Where I need the calling method.
})
)
);
public async Task DoSomeWork() { //<--- I want to get "DoSomeWork"
// Some work..
await dbConn.SaveChangesAsync();
return updated;
}
How can I get access to the method which called .saveChangesAsync so I know where it was triggered from? I've checked using StackTrace
however that is flooded with library level frames which are not very helpful and I can't find the correct parent method.
I see in evt
there is a that it provides a calling parent name, however that is just one level up so is just the "SaveChangesAsync" method.
Thanks
CodePudding user response:
If you can change the code that calls SaveChangesAsync
and you are inheriting your DbContext from AuditDbContext (High-Level SaveChanges interception), then you could add a new SaveChanges method with an optional parameter decorated with [CallerMemberName]
and store the caller member name in a custom field of the AuditEvent.
For example:
public class YourDbContext : AuditDbContext
{
public override Task<int> SaveChangesAsync(CancellationToken cancellationToken = default)
=> throw new NotImplementedException("Should call SaveChangesAuditAsync");
public Task<int> SaveChangesAuditAsync([CallerMemberName] string memberName = "", CancellationToken cancellationToken = default)
{
this.AddAuditCustomField("Caller", memberName);
return base.SaveChangesAsync(cancellationToken);
}
}
So, in your AuditEntityAction you can get the caller member name from the custom field:
...
.AuditEntityAction<AuditLog>((evt, entry, auditEntity) =>
{
auditEntity.CallingMethod = evt.CustomFields["Caller"];
})
Now your DoSomeWork()
must call the new method:
public async Task DoSomeWork()
{
...
await dbConn.SaveChangesAuditAsync();
return updated;
}