IntegrationEventLogService refactoring
This commit is contained in:
		
							parent
							
								
									45499808b9
								
							
						
					
					
						commit
						0372fada82
					
				| @ -1,14 +1,15 @@ | |||||||
| using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events; | using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events; | ||||||
| using System; | using System; | ||||||
| using System.Collections.Generic; | using System.Collections.Generic; | ||||||
|  | using System.Data.Common; | ||||||
| using System.Linq; | using System.Linq; | ||||||
| using System.Threading.Tasks; | using System.Threading.Tasks; | ||||||
| 
 | 
 | ||||||
| namespace Catalog.API.IntegrationEvents | namespace Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF.Services | ||||||
| { | { | ||||||
|     public interface IIntegrationEventLogService |     public interface IIntegrationEventLogService | ||||||
|     { |     { | ||||||
|         Task SaveEventAsync(IntegrationEvent @event); |         Task SaveEventAsync(IntegrationEvent @event, DbTransaction transaction); | ||||||
|         Task MarkEventAsPublishedAsync(IntegrationEvent @event); |         Task MarkEventAsPublishedAsync(IntegrationEvent @event); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| @ -1,37 +1,39 @@ | |||||||
| using System; | using Microsoft.EntityFrameworkCore; | ||||||
| using System.Collections.Generic; | using Microsoft.EntityFrameworkCore.Infrastructure; | ||||||
|  | using Microsoft.EntityFrameworkCore.Storage; | ||||||
|  | using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events; | ||||||
|  | using System.Data.Common; | ||||||
| using System.Linq; | using System.Linq; | ||||||
| using System.Threading.Tasks; | using System.Threading.Tasks; | ||||||
| using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events; | using System; | ||||||
| using Microsoft.eShopOnContainers.Services.Catalog.API.Infrastructure; |  | ||||||
| using Microsoft.EntityFrameworkCore; |  | ||||||
| using Microsoft.EntityFrameworkCore.Storage; |  | ||||||
| using Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF; |  | ||||||
| using Microsoft.EntityFrameworkCore.Infrastructure; |  | ||||||
| 
 | 
 | ||||||
| namespace Catalog.API.IntegrationEvents | namespace Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF.Services | ||||||
| { | { | ||||||
|     public class IntegrationEventLogService : IIntegrationEventLogService |     public class IntegrationEventLogService : IIntegrationEventLogService | ||||||
|     { |     { | ||||||
|         private readonly IntegrationEventLogContext _integrationEventLogContext; |         private readonly IntegrationEventLogContext _integrationEventLogContext; | ||||||
|         private readonly CatalogContext _catalogContext; |         private readonly DbConnection _dbConnection; | ||||||
| 
 | 
 | ||||||
|         public IntegrationEventLogService(CatalogContext catalogContext) |         public IntegrationEventLogService(DbConnection dbConnection) | ||||||
|         { |         { | ||||||
|             _catalogContext = catalogContext; |             _dbConnection = dbConnection?? throw new ArgumentNullException("dbConnection"); | ||||||
|             _integrationEventLogContext = new IntegrationEventLogContext( |             _integrationEventLogContext = new IntegrationEventLogContext( | ||||||
|                 new DbContextOptionsBuilder<IntegrationEventLogContext>() |                 new DbContextOptionsBuilder<IntegrationEventLogContext>() | ||||||
|                     .UseSqlServer(catalogContext.Database.GetDbConnection()) |                     .UseSqlServer(_dbConnection) | ||||||
|                     .ConfigureWarnings(warnings => warnings.Throw(RelationalEventId.QueryClientEvaluationWarning)) |                     .ConfigureWarnings(warnings => warnings.Throw(RelationalEventId.QueryClientEvaluationWarning)) | ||||||
|                     .Options); |                     .Options); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         public Task SaveEventAsync(IntegrationEvent @event) |         public Task SaveEventAsync(IntegrationEvent @event, DbTransaction transaction) | ||||||
|         { |         { | ||||||
|  |             if(transaction == null) | ||||||
|  |             { | ||||||
|  |                 throw new ArgumentNullException("transaction", $"A {typeof(DbTransaction).FullName} is required as a pre-requisite to save the event."); | ||||||
|  |             } | ||||||
|  |              | ||||||
|             var eventLogEntry = new IntegrationEventLogEntry(@event); |             var eventLogEntry = new IntegrationEventLogEntry(@event); | ||||||
|              |              | ||||||
|             // as a constraint this transaction has to be done together with a catalogContext transaction |             _integrationEventLogContext.Database.UseTransaction(transaction); | ||||||
|             _integrationEventLogContext.Database.UseTransaction(_catalogContext.Database.CurrentTransaction.GetDbTransaction()); |  | ||||||
|             _integrationEventLogContext.IntegrationEventLogs.Add(eventLogEntry); |             _integrationEventLogContext.IntegrationEventLogs.Add(eventLogEntry); | ||||||
| 
 | 
 | ||||||
|             return _integrationEventLogContext.SaveChangesAsync(); |             return _integrationEventLogContext.SaveChangesAsync(); | ||||||
| @ -1,15 +1,17 @@ | |||||||
| using Catalog.API.IntegrationEvents; | using Microsoft.AspNetCore.Mvc; | ||||||
| using Microsoft.AspNetCore.Mvc; |  | ||||||
| using Microsoft.EntityFrameworkCore; | using Microsoft.EntityFrameworkCore; | ||||||
| using Microsoft.EntityFrameworkCore.Storage; | using Microsoft.EntityFrameworkCore.Storage; | ||||||
|  | using Microsoft.EntityFrameworkCore.Infrastructure; | ||||||
| using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions; | using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions; | ||||||
| using Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF; | using Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF.Services; | ||||||
| using Microsoft.eShopOnContainers.Services.Catalog.API.Infrastructure; | using Microsoft.eShopOnContainers.Services.Catalog.API.Infrastructure; | ||||||
| using Microsoft.eShopOnContainers.Services.Catalog.API.IntegrationEvents.Events; | using Microsoft.eShopOnContainers.Services.Catalog.API.IntegrationEvents.Events; | ||||||
| using Microsoft.eShopOnContainers.Services.Catalog.API.Model; | using Microsoft.eShopOnContainers.Services.Catalog.API.Model; | ||||||
| using Microsoft.eShopOnContainers.Services.Catalog.API.ViewModel; | using Microsoft.eShopOnContainers.Services.Catalog.API.ViewModel; | ||||||
| using Microsoft.Extensions.Options; | using Microsoft.Extensions.Options; | ||||||
|  | using System; | ||||||
| using System.Collections.Generic; | using System.Collections.Generic; | ||||||
|  | using System.Data.Common; | ||||||
| using System.Linq; | using System.Linq; | ||||||
| using System.Threading.Tasks; | using System.Threading.Tasks; | ||||||
| 
 | 
 | ||||||
| @ -21,14 +23,14 @@ namespace Microsoft.eShopOnContainers.Services.Catalog.API.Controllers | |||||||
|         private readonly CatalogContext _catalogContext; |         private readonly CatalogContext _catalogContext; | ||||||
|         private readonly IOptionsSnapshot<Settings> _settings; |         private readonly IOptionsSnapshot<Settings> _settings; | ||||||
|         private readonly IEventBus _eventBus; |         private readonly IEventBus _eventBus; | ||||||
|         private readonly IIntegrationEventLogService _integrationEventLogService; |         private readonly Func<DbConnection, IIntegrationEventLogService> _integrationEventLogServiceFactory; | ||||||
| 
 | 
 | ||||||
|         public CatalogController(CatalogContext Context, IOptionsSnapshot<Settings> settings, IEventBus eventBus, IIntegrationEventLogService integrationEventLogService) |         public CatalogController(CatalogContext Context, IOptionsSnapshot<Settings> settings, IEventBus eventBus, Func<DbConnection, IIntegrationEventLogService> integrationEventLogServiceFactory) | ||||||
|         { |         { | ||||||
|             _catalogContext = Context; |             _catalogContext = Context; | ||||||
|             _settings = settings; |             _settings = settings; | ||||||
|             _eventBus = eventBus; |             _eventBus = eventBus; | ||||||
|             _integrationEventLogService = integrationEventLogService; |             _integrationEventLogServiceFactory = integrationEventLogServiceFactory; | ||||||
| 
 | 
 | ||||||
|             ((DbContext)Context).ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking; |             ((DbContext)Context).ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking; | ||||||
|         } |         } | ||||||
| @ -152,20 +154,22 @@ namespace Microsoft.eShopOnContainers.Services.Catalog.API.Controllers | |||||||
|                 var oldPrice = item.Price; |                 var oldPrice = item.Price; | ||||||
|                 item.Price = product.Price; |                 item.Price = product.Price; | ||||||
|                 var @event = new ProductPriceChangedIntegrationEvent(item.Id, item.Price, oldPrice); |                 var @event = new ProductPriceChangedIntegrationEvent(item.Id, item.Price, oldPrice); | ||||||
|  |                 var eventLogService = _integrationEventLogServiceFactory(_catalogContext.Database.GetDbConnection()); | ||||||
| 
 | 
 | ||||||
|                 using (var transaction = _catalogContext.Database.BeginTransaction()) |                 using (var transaction = _catalogContext.Database.BeginTransaction()) | ||||||
|                 { |                 { | ||||||
|                     _catalogContext.CatalogItems.Update(item); |                     _catalogContext.CatalogItems.Update(item); | ||||||
|                     await _catalogContext.SaveChangesAsync(); |                     await _catalogContext.SaveChangesAsync(); | ||||||
| 
 | 
 | ||||||
|                     await _integrationEventLogService.SaveEventAsync(@event); | 
 | ||||||
|  |                     await eventLogService.SaveEventAsync(@event, _catalogContext.Database.CurrentTransaction.GetDbTransaction()); | ||||||
| 
 | 
 | ||||||
|                     transaction.Commit(); |                     transaction.Commit(); | ||||||
|                 } |                 } | ||||||
| 
 | 
 | ||||||
|                 _eventBus.Publish(@event); |                 _eventBus.Publish(@event); | ||||||
| 
 | 
 | ||||||
|                 await _integrationEventLogService.MarkEventAsPublishedAsync(@event);                |                 await eventLogService.MarkEventAsPublishedAsync(@event);                | ||||||
|             }          |             }          | ||||||
| 
 | 
 | ||||||
|             return Ok(); |             return Ok(); | ||||||
|  | |||||||
| @ -1,6 +1,5 @@ | |||||||
| namespace Microsoft.eShopOnContainers.Services.Catalog.API | namespace Microsoft.eShopOnContainers.Services.Catalog.API | ||||||
| { | { | ||||||
|     using global::Catalog.API.IntegrationEvents; |  | ||||||
|     using Microsoft.AspNetCore.Builder; |     using Microsoft.AspNetCore.Builder; | ||||||
|     using Microsoft.AspNetCore.Hosting; |     using Microsoft.AspNetCore.Hosting; | ||||||
|     using Microsoft.EntityFrameworkCore; |     using Microsoft.EntityFrameworkCore; | ||||||
| @ -8,12 +7,14 @@ | |||||||
|     using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions; |     using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions; | ||||||
|     using Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ; |     using Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ; | ||||||
|     using Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF; |     using Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF; | ||||||
|  |     using Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF.Services; | ||||||
|     using Microsoft.eShopOnContainers.Services.Catalog.API.Infrastructure; |     using Microsoft.eShopOnContainers.Services.Catalog.API.Infrastructure; | ||||||
|     using Microsoft.Extensions.Configuration; |     using Microsoft.Extensions.Configuration; | ||||||
|     using Microsoft.Extensions.DependencyInjection; |     using Microsoft.Extensions.DependencyInjection; | ||||||
|     using Microsoft.Extensions.Logging; |     using Microsoft.Extensions.Logging; | ||||||
|     using Microsoft.Extensions.Options; |     using Microsoft.Extensions.Options; | ||||||
|     using System.Data.SqlClient; |     using System; | ||||||
|  |     using System.Data.Common; | ||||||
|     using System.Reflection; |     using System.Reflection; | ||||||
| 
 | 
 | ||||||
|     public class Startup |     public class Startup | ||||||
| @ -39,23 +40,15 @@ | |||||||
| 
 | 
 | ||||||
|         public void ConfigureServices(IServiceCollection services) |         public void ConfigureServices(IServiceCollection services) | ||||||
|         { |         { | ||||||
|             var sqlConnection = new SqlConnection(Configuration["ConnectionString"]); |  | ||||||
| 
 |  | ||||||
|             services.AddDbContext<CatalogContext>(c => |             services.AddDbContext<CatalogContext>(c => | ||||||
|             { |             { | ||||||
|                 c.UseSqlServer(sqlConnection); |                 c.UseSqlServer(Configuration["ConnectionString"]); | ||||||
|                 // Changing default behavior when client evaluation occurs to throw.  |                 // Changing default behavior when client evaluation occurs to throw.  | ||||||
|                 // Default in EF Core would be to log a warning when client evaluation is performed. |                 // Default in EF Core would be to log a warning when client evaluation is performed. | ||||||
|                 c.ConfigureWarnings(warnings => warnings.Throw(RelationalEventId.QueryClientEvaluationWarning)); |                 c.ConfigureWarnings(warnings => warnings.Throw(RelationalEventId.QueryClientEvaluationWarning)); | ||||||
|                 //Check Client vs. Server evaluation: https://docs.microsoft.com/en-us/ef/core/querying/client-eval |                 //Check Client vs. Server evaluation: https://docs.microsoft.com/en-us/ef/core/querying/client-eval | ||||||
|             }); |             }); | ||||||
| 
 | 
 | ||||||
|             services.AddDbContext<IntegrationEventLogContext>(c => |  | ||||||
|             { |  | ||||||
|                 c.UseSqlServer(sqlConnection, b => b.MigrationsAssembly("Catalog.API"));                |  | ||||||
|                 c.ConfigureWarnings(warnings => warnings.Throw(RelationalEventId.QueryClientEvaluationWarning));                 |  | ||||||
|             }); |  | ||||||
| 
 |  | ||||||
|             services.Configure<Settings>(Configuration); |             services.Configure<Settings>(Configuration); | ||||||
| 
 | 
 | ||||||
|             // Add framework services. |             // Add framework services. | ||||||
| @ -81,8 +74,9 @@ | |||||||
|                     .AllowCredentials()); |                     .AllowCredentials()); | ||||||
|             }); |             }); | ||||||
| 
 | 
 | ||||||
|             services.AddTransient<IIntegrationEventLogService, IntegrationEventLogService>(); |             services.AddTransient<Func<DbConnection, IIntegrationEventLogService>>( | ||||||
|              |                 sp => (DbConnection c) => new IntegrationEventLogService(c)); | ||||||
|  | 
 | ||||||
|             var serviceProvider = services.BuildServiceProvider(); |             var serviceProvider = services.BuildServiceProvider(); | ||||||
|             var configuration = serviceProvider.GetRequiredService<IOptionsSnapshot<Settings>>().Value; |             var configuration = serviceProvider.GetRequiredService<IOptionsSnapshot<Settings>>().Value; | ||||||
|             services.AddSingleton<IEventBus>(new EventBusRabbitMQ(configuration.EventBusConnection)); |             services.AddSingleton<IEventBus>(new EventBusRabbitMQ(configuration.EventBusConnection)); | ||||||
| @ -90,7 +84,7 @@ | |||||||
|             services.AddMvc(); |             services.AddMvc(); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory, IntegrationEventLogContext integrationEventLogContext) |         public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) | ||||||
|         { |         { | ||||||
|             //Configure logs |             //Configure logs | ||||||
| 
 | 
 | ||||||
| @ -112,7 +106,11 @@ | |||||||
|             //Seed Data |             //Seed Data | ||||||
|             CatalogContextSeed.SeedAsync(app, loggerFactory) |             CatalogContextSeed.SeedAsync(app, loggerFactory) | ||||||
|                 .Wait(); |                 .Wait(); | ||||||
|              | 
 | ||||||
|  |             var integrationEventLogContext = new IntegrationEventLogContext( | ||||||
|  |                 new DbContextOptionsBuilder<IntegrationEventLogContext>() | ||||||
|  |                 .UseSqlServer(Configuration["ConnectionString"], b => b.MigrationsAssembly("Catalog.API"))                 | ||||||
|  |                 .Options); | ||||||
|             integrationEventLogContext.Database.Migrate(); |             integrationEventLogContext.Database.Migrate(); | ||||||
| 
 | 
 | ||||||
|         } |         } | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user