Code re-factorings and formatting in IntegrationEventLogEF project
This commit is contained in:
parent
0705dc0ab5
commit
1d377f7808
@ -1,13 +1,9 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF
|
||||
namespace Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF
|
||||
{
|
||||
public enum EventStateEnum
|
||||
{
|
||||
NotPublished = 0,
|
||||
Published = 1,
|
||||
PublishedFailed = 2
|
||||
}
|
||||
public enum EventStateEnum
|
||||
{
|
||||
NotPublished = 0,
|
||||
Published = 1,
|
||||
PublishedFailed = 2
|
||||
}
|
||||
}
|
||||
|
@ -1,48 +1,45 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF
|
||||
{
|
||||
public class IntegrationEventLogContext : DbContext
|
||||
{
|
||||
public IntegrationEventLogContext(DbContextOptions<IntegrationEventLogContext> options) : base(options)
|
||||
{
|
||||
}
|
||||
public class IntegrationEventLogContext : DbContext
|
||||
{
|
||||
public IntegrationEventLogContext(DbContextOptions<IntegrationEventLogContext> options) : base(options)
|
||||
{
|
||||
}
|
||||
|
||||
public DbSet<IntegrationEventLogEntry> IntegrationEventLogs { get; set; }
|
||||
public DbSet<IntegrationEventLogEntry> IntegrationEventLogs { get; set; }
|
||||
|
||||
protected override void OnModelCreating(ModelBuilder builder)
|
||||
{
|
||||
builder.Entity<IntegrationEventLogEntry>(ConfigureIntegrationEventLogEntry);
|
||||
}
|
||||
protected override void OnModelCreating(ModelBuilder builder)
|
||||
{
|
||||
builder.Entity<IntegrationEventLogEntry>(ConfigureIntegrationEventLogEntry);
|
||||
}
|
||||
|
||||
void ConfigureIntegrationEventLogEntry(EntityTypeBuilder<IntegrationEventLogEntry> builder)
|
||||
{
|
||||
builder.ToTable("IntegrationEventLog");
|
||||
void ConfigureIntegrationEventLogEntry(EntityTypeBuilder<IntegrationEventLogEntry> builder)
|
||||
{
|
||||
builder.ToTable("IntegrationEventLog");
|
||||
|
||||
builder.HasKey(e => e.EventId);
|
||||
builder.HasKey(e => e.EventId);
|
||||
|
||||
builder.Property(e => e.EventId)
|
||||
.IsRequired();
|
||||
builder.Property(e => e.EventId)
|
||||
.IsRequired();
|
||||
|
||||
builder.Property(e => e.Content)
|
||||
.IsRequired();
|
||||
builder.Property(e => e.Content)
|
||||
.IsRequired();
|
||||
|
||||
builder.Property(e => e.CreationTime)
|
||||
.IsRequired();
|
||||
builder.Property(e => e.CreationTime)
|
||||
.IsRequired();
|
||||
|
||||
builder.Property(e => e.State)
|
||||
.IsRequired();
|
||||
builder.Property(e => e.State)
|
||||
.IsRequired();
|
||||
|
||||
builder.Property(e => e.TimesSent)
|
||||
.IsRequired();
|
||||
builder.Property(e => e.TimesSent)
|
||||
.IsRequired();
|
||||
|
||||
builder.Property(e => e.EventTypeName)
|
||||
.IsRequired();
|
||||
builder.Property(e => e.EventTypeName)
|
||||
.IsRequired();
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,28 +1,28 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Newtonsoft.Json;
|
||||
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events;
|
||||
using DateTime = System.DateTime;
|
||||
using Guid = System.Guid;
|
||||
using JsonConvert = Newtonsoft.Json.JsonConvert;
|
||||
|
||||
namespace Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF
|
||||
{
|
||||
public class IntegrationEventLogEntry
|
||||
{
|
||||
private IntegrationEventLogEntry() { }
|
||||
public IntegrationEventLogEntry(IntegrationEvent @event)
|
||||
{
|
||||
EventId = @event.Id;
|
||||
CreationTime = @event.CreationDate;
|
||||
EventTypeName = @event.GetType().FullName;
|
||||
Content = JsonConvert.SerializeObject(@event);
|
||||
State = EventStateEnum.NotPublished;
|
||||
TimesSent = 0;
|
||||
}
|
||||
public Guid EventId { get; private set; }
|
||||
public string EventTypeName { get; private set; }
|
||||
public EventStateEnum State { get; set; }
|
||||
public int TimesSent { get; set; }
|
||||
public DateTime CreationTime { get; private set; }
|
||||
public string Content { get; private set; }
|
||||
}
|
||||
using IntegrationEvent = EventBus.Events.IntegrationEvent;
|
||||
|
||||
public class IntegrationEventLogEntry
|
||||
{
|
||||
private IntegrationEventLogEntry() { }
|
||||
public IntegrationEventLogEntry(IntegrationEvent @event)
|
||||
{
|
||||
EventId = @event.Id;
|
||||
CreationTime = @event.CreationDate;
|
||||
EventTypeName = @event.GetType().FullName;
|
||||
Content = JsonConvert.SerializeObject(@event);
|
||||
State = EventStateEnum.NotPublished;
|
||||
TimesSent = 0;
|
||||
}
|
||||
public Guid EventId { get; private set; }
|
||||
public string EventTypeName { get; private set; }
|
||||
public EventStateEnum State { get; set; }
|
||||
public int TimesSent { get; set; }
|
||||
public DateTime CreationTime { get; private set; }
|
||||
public string Content { get; private set; }
|
||||
}
|
||||
}
|
||||
|
@ -1,15 +1,13 @@
|
||||
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data.Common;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using DbTransaction = System.Data.Common.DbTransaction;
|
||||
using Task = System.Threading.Tasks.Task;
|
||||
|
||||
namespace Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF.Services
|
||||
{
|
||||
public interface IIntegrationEventLogService
|
||||
{
|
||||
Task SaveEventAsync(IntegrationEvent @event, DbTransaction transaction);
|
||||
Task MarkEventAsPublishedAsync(IntegrationEvent @event);
|
||||
}
|
||||
using IntegrationEvent = EventBus.Events.IntegrationEvent;
|
||||
|
||||
public interface IIntegrationEventLogService
|
||||
{
|
||||
Task SaveEventAsync(IntegrationEvent @event, DbTransaction transaction);
|
||||
Task MarkEventAsPublishedAsync(IntegrationEvent @event);
|
||||
}
|
||||
}
|
||||
|
@ -1,52 +1,54 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Diagnostics;
|
||||
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events;
|
||||
using System;
|
||||
using System.Data.Common;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using static System.Linq.Enumerable;
|
||||
using ArgumentNullException = System.ArgumentNullException;
|
||||
using DbConnection = System.Data.Common.DbConnection;
|
||||
using DbTransaction = System.Data.Common.DbTransaction;
|
||||
using RelationalEventId = Microsoft.EntityFrameworkCore.Diagnostics.RelationalEventId;
|
||||
using Task = System.Threading.Tasks.Task;
|
||||
|
||||
namespace Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF.Services
|
||||
{
|
||||
public class IntegrationEventLogService : IIntegrationEventLogService
|
||||
{
|
||||
private readonly IntegrationEventLogContext _integrationEventLogContext;
|
||||
private readonly DbConnection _dbConnection;
|
||||
using IntegrationEvent = EventBus.Events.IntegrationEvent;
|
||||
|
||||
public IntegrationEventLogService(DbConnection dbConnection)
|
||||
{
|
||||
_dbConnection = dbConnection ?? throw new ArgumentNullException(nameof(dbConnection));
|
||||
_integrationEventLogContext = new IntegrationEventLogContext(
|
||||
new DbContextOptionsBuilder<IntegrationEventLogContext>()
|
||||
.UseSqlServer(_dbConnection)
|
||||
.ConfigureWarnings(warnings => warnings.Throw(RelationalEventId.QueryClientEvaluationWarning))
|
||||
.Options);
|
||||
}
|
||||
public class IntegrationEventLogService : IIntegrationEventLogService
|
||||
{
|
||||
private readonly IntegrationEventLogContext _integrationEventLogContext;
|
||||
private readonly DbConnection _dbConnection;
|
||||
|
||||
public Task SaveEventAsync(IntegrationEvent @event, DbTransaction transaction)
|
||||
{
|
||||
if (transaction == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(transaction), $"A {typeof(DbTransaction).FullName} is required as a pre-requisite to save the event.");
|
||||
}
|
||||
public IntegrationEventLogService(DbConnection dbConnection)
|
||||
{
|
||||
_dbConnection = dbConnection ?? throw new ArgumentNullException(nameof(dbConnection));
|
||||
_integrationEventLogContext = new IntegrationEventLogContext(
|
||||
new DbContextOptionsBuilder<IntegrationEventLogContext>()
|
||||
.UseSqlServer(_dbConnection)
|
||||
.ConfigureWarnings(warnings => warnings.Throw(RelationalEventId.QueryClientEvaluationWarning))
|
||||
.Options);
|
||||
}
|
||||
|
||||
var eventLogEntry = new IntegrationEventLogEntry(@event);
|
||||
public Task SaveEventAsync(IntegrationEvent @event, DbTransaction transaction)
|
||||
{
|
||||
if (transaction == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(transaction), $"A {typeof(DbTransaction).FullName} is required as a pre-requisite to save the event.");
|
||||
}
|
||||
|
||||
_integrationEventLogContext.Database.UseTransaction(transaction);
|
||||
_integrationEventLogContext.IntegrationEventLogs.Add(eventLogEntry);
|
||||
var eventLogEntry = new IntegrationEventLogEntry(@event);
|
||||
|
||||
return _integrationEventLogContext.SaveChangesAsync();
|
||||
}
|
||||
_integrationEventLogContext.Database.UseTransaction(transaction);
|
||||
_integrationEventLogContext.IntegrationEventLogs.Add(eventLogEntry);
|
||||
|
||||
public Task MarkEventAsPublishedAsync(IntegrationEvent @event)
|
||||
{
|
||||
var eventLogEntry = _integrationEventLogContext.IntegrationEventLogs.Single(ie => ie.EventId == @event.Id);
|
||||
eventLogEntry.TimesSent++;
|
||||
eventLogEntry.State = EventStateEnum.Published;
|
||||
return _integrationEventLogContext.SaveChangesAsync();
|
||||
}
|
||||
|
||||
_integrationEventLogContext.IntegrationEventLogs.Update(eventLogEntry);
|
||||
public Task MarkEventAsPublishedAsync(IntegrationEvent @event)
|
||||
{
|
||||
var eventLogEntry = _integrationEventLogContext.IntegrationEventLogs.Single(ie => ie.EventId == @event.Id);
|
||||
eventLogEntry.TimesSent++;
|
||||
eventLogEntry.State = EventStateEnum.Published;
|
||||
|
||||
return _integrationEventLogContext.SaveChangesAsync();
|
||||
}
|
||||
}
|
||||
_integrationEventLogContext.IntegrationEventLogs.Update(eventLogEntry);
|
||||
|
||||
return _integrationEventLogContext.SaveChangesAsync();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,37 +1,35 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Storage;
|
||||
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events;
|
||||
using Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF.Services;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data.Common;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using static Microsoft.EntityFrameworkCore.ExecutionStrategyExtensions;
|
||||
using ArgumentNullException = System.ArgumentNullException;
|
||||
using DbContext = Microsoft.EntityFrameworkCore.DbContext;
|
||||
using Task = System.Threading.Tasks.Task;
|
||||
|
||||
|
||||
namespace Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF.Utilities
|
||||
{
|
||||
public class ResilientTransaction
|
||||
{
|
||||
private DbContext _context;
|
||||
private ResilientTransaction(DbContext context) =>
|
||||
_context = context ?? throw new ArgumentNullException(nameof(context));
|
||||
using FuncOfTask = System.Func<Task>;
|
||||
|
||||
public static ResilientTransaction New (DbContext context) =>
|
||||
new ResilientTransaction(context);
|
||||
public class ResilientTransaction
|
||||
{
|
||||
private DbContext _context;
|
||||
private ResilientTransaction(DbContext context) =>
|
||||
_context = context ?? throw new ArgumentNullException(nameof(context));
|
||||
|
||||
public async Task ExecuteAsync(Func<Task> action)
|
||||
{
|
||||
//Use of an EF Core resiliency strategy when using multiple DbContexts within an explicit BeginTransaction():
|
||||
//See: https://docs.microsoft.com/en-us/ef/core/miscellaneous/connection-resiliency
|
||||
var strategy = _context.Database.CreateExecutionStrategy();
|
||||
await strategy.ExecuteAsync(async () =>
|
||||
{
|
||||
using (var transaction = _context.Database.BeginTransaction())
|
||||
{
|
||||
await action();
|
||||
transaction.Commit();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
public static ResilientTransaction New(DbContext context) =>
|
||||
new ResilientTransaction(context);
|
||||
|
||||
public async Task ExecuteAsync(FuncOfTask action)
|
||||
{
|
||||
//Use of an EF Core resiliency strategy when using multiple DbContexts within an explicit BeginTransaction():
|
||||
//See: https://docs.microsoft.com/en-us/ef/core/miscellaneous/connection-resiliency
|
||||
var strategy = _context.Database.CreateExecutionStrategy();
|
||||
await strategy.ExecuteAsync(async () =>
|
||||
{
|
||||
using (var transaction = _context.Database.BeginTransaction())
|
||||
{
|
||||
await action();
|
||||
transaction.Commit();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user