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