Simple implementation of audit and event sourcing based on QueryPack.DispatchProxy
$ dotnet add package QueryPack.AuditSimple implementation of audit based on QueryPack.DispatchProxy
dotnet add package QueryPack.Audit
class EntityAuditConfiguration : IAuditConfiguration<AuditContext, IEntityService>
{
public void Configure(IAuditConfigurator<AuditContext, IEntityService> configurator)
{
configurator.Add(builder
=> builder.OnMethodExecuting<string, EntityArg, CancellationToken,
Task<EntityResult>>(e => e.CreateAsync,
async (ctx, service, id, arg, token, invoker) =>
{
var result = await invoker.Invoke();
ctx.Sender.Send(result);
return result;
}));
}
}
Programstatic IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args)
.ConfigureServices((hostContext, services) =>
{
services.AddTransient<IEntityService, EntityService>();
services.AddAudit(regestry =>
regestry.ConfigureOptions(options =>
{
options.QueueReadBatchSize = 50;
options.QueueReadIntervalInSeconds = 5;
options.ReceiveTimeoutInSeconds = 15;
})
.AddContext<AuditContext>()
.AddReceiver<EntityResult, EntityResultAuditableReceiver>()
.AuditFor(new EntityAuditConfiguration()));
});
class EntityResultAuditableReceiver : IAuditableReceiver<EntityResult>
{
public Task<IEnumerable<EntityResult>> ReceiveAsync(IEnumerable<EntityResult> auditables, CancellationToken cancellationToken)
{
// code is here
// return empty collection in case if there are no errors
return Task.FromResult(Enumerable.Empty<EntityResult>());
}
}
IEntityService entitySerice;
var result = await entitySerice.CreateAsync("some_id", new EntityArg(), CancellationToken.None);