Replies: 2 comments 11 replies
-
I don't understand the issue, you have to provide more information, and a code sample explaining what are you trying to accomplish and what you've tried so far. What do you mean by "My aggregate is publishing events"? |
Beta Was this translation helpful? Give feedback.
-
The latest version 27.3.1 includes a new DbContext DataProvider as a generic audit data provider that uses Entity Framework Core to write audit events. It allows mapping audit events to a specific entity in a DbContext. I think this can be helpful for your use case. In the following example, the The The using Audit.Core;
using Audit.EntityFramework.Providers;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
// *************
// Startup Code:
// *************
// Register the services
var serviceProvider = new ServiceCollection()
.AddScoped<IMyService, MyService>()
.AddScoped<IMyAuditLogger, MyAuditLogger>()
.AddSingleton<IAuditScopeFactory, AuditScopeFactory>()
.AddDbContextFactory<MyDbContext>()
.BuildServiceProvider();
// ***************************************
// Simulate a MyService.ExecuteAsync call:
// ***************************************
var service = serviceProvider.GetService<IMyService>();
await service.ExecuteAsync();
// *************
// Service Code:
// *************
public interface IMyService
{
Task ExecuteAsync();
}
public class MyService : IMyService
{
private readonly IDbContextFactory<MyDbContext> _contextFactory;
private readonly IMyAuditLogger _auditLogger;
public MyService(IDbContextFactory<MyDbContext> contextFactory, IMyAuditLogger auditLogger)
{
_contextFactory = contextFactory;
_auditLogger = auditLogger;
}
public async Task ExecuteAsync()
{
// Create a new DbContext instance
await using var dbContext = await _contextFactory.CreateDbContextAsync();
// Start a new transaction
await using var tran = await dbContext.Database.BeginTransactionAsync();
// Add a new Order
await dbContext.Orders.AddAsync(new Order()
{
OrderDate = DateTime.Now,
OrderStatus = "C",
OrderLines =
[
new OrderLine() { ProductCode = "A1", Quantity = 2 },
new OrderLine() { ProductCode = "B2", Quantity = 3 }
]
});
// Save the database changes
await dbContext.SaveChangesAsync();
// Log the audit event within the same transaction
await _auditLogger.LogAsync("LogTest", new { CustomField = "Test" }, dbContext);
// Commit the transaction
await tran.CommitAsync();
}
}
public interface IMyAuditLogger
{
Task LogAsync(string eventType, object customFields, MyDbContext dbContext);
}
public class MyAuditLogger : IMyAuditLogger
{
private readonly IAuditScopeFactory _auditScopeFactory;
public MyAuditLogger(IAuditScopeFactory auditScopeFactory)
{
_auditScopeFactory = auditScopeFactory;
}
// Your custom log method
public async Task LogAsync(string eventType, object customFields, MyDbContext dbContext)
{
// Logic is similar to the static AuditScope.LogAsync(), but using the audit scope factory
// and setting the data provider to save the audit logs using MyDbContext and AuditLog
await _auditScopeFactory.CreateAsync(f => f
.EventType(eventType)
.ExtraFields(customFields)
.IsCreateAndSave()
.DataProvider(new DbContextDataProvider<MyDbContext, AuditLog>(c => c
.DbContext(dbContext)
.Mapper((auditEvent, auditLog) =>
{
auditLog.AuditDate = DateTime.Now;
auditLog.Data = auditEvent.ToJson();
}))));
}
}
// Sample DbContext including Orders and AuditLogs
public class MyDbContext : DbContext
{
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer("data source=localhost;initial catalog=Audit_10;integrated security=true;Encrypt=False;");
}
public DbSet<Order> Orders { get; set; }
public DbSet<AuditLog> AuditLogs { get; set; }
}
public class Order
{
public int Id { get; set; }
public DateTime OrderDate { get; set; }
public string OrderStatus { get; set; }
public List<OrderLine> OrderLines { get; set; }
}
public class OrderLine
{
public int Id { get; set; }
public int Quantity { set; get; }
public string ProductCode { set; get; }
public int OrderId { get; set; }
public Order Order { get; set; }
}
public class AuditLog
{
public int Id { get; set; }
public DateTime AuditDate { get; set; }
public string Data { get; set; }
} Hope it helps |
Beta Was this translation helpful? Give feedback.
-
My aggregate is publishing events.
I don't want to audit the entities (thus not using Audit EF package), but I want to save published events as audit events within the same transaction.
Is it possible?
Beta Was this translation helpful? Give feedback.
All reactions