From ad166313d35153bf6a7e57cc93bfe73badabbe7b Mon Sep 17 00:00:00 2001 From: StuartFerguson Date: Thu, 25 Jun 2026 17:16:30 +0100 Subject: [PATCH 1/4] further fix for dispose issues --- ...TransactionProcessorReadModelRepository.cs | 278 ++++++++++++------ ...actionProcessorReadModelRepositoryTests.cs | 84 ++++++ .../TransactionProcessor.Tests.csproj | 1 + 3 files changed, 266 insertions(+), 97 deletions(-) create mode 100644 TransactionProcessor.Tests/RepositoryTests/TransactionProcessorReadModelRepositoryTests.cs diff --git a/TransactionProcessor.Repository/ITransactionProcessorReadModelRepository.cs b/TransactionProcessor.Repository/ITransactionProcessorReadModelRepository.cs index 4b426c6b..14de75e7 100644 --- a/TransactionProcessor.Repository/ITransactionProcessorReadModelRepository.cs +++ b/TransactionProcessor.Repository/ITransactionProcessorReadModelRepository.cs @@ -1,4 +1,4 @@ -using FileProcessor.File.DomainEvents; +using FileProcessor.File.DomainEvents; using FileProcessor.FileImportLog.DomainEvents; using Microsoft.EntityFrameworkCore; using Shared.DomainDrivenDesign.EventSourcing; @@ -323,7 +323,8 @@ public TransactionProcessorReadModelRepository(IDbContextResolver UpdateMerchant(StatementGeneratedEvent domainEvent, CancellationToken cancellationToken) { - EstateManagementContext context = await this.GetContext(domainEvent.EstateId); + using ResolvedDbContext? resolvedContext = this.Resolver.Resolve(EstateManagementDatabaseName, domainEvent.EstateId.ToString()); + await using EstateManagementContext context = resolvedContext.Context; Result merchantResult = await context.LoadMerchant(domainEvent, cancellationToken); if (merchantResult.IsFailed) @@ -341,7 +342,8 @@ public async Task> GetMerchantFromReference(Guid estateId, String reference, CancellationToken cancellationToken) { - EstateManagementContext context = await this.GetContext(estateId); + using ResolvedDbContext? resolvedContext = this.Resolver.Resolve(EstateManagementDatabaseName, estateId.ToString()); + await using EstateManagementContext context = resolvedContext.Context; Merchant merchant = await (from m in context.Merchants where m.Reference == reference select m).SingleOrDefaultAsync(cancellationToken); @@ -354,7 +356,8 @@ public async Task> GetMerchantFromReference(Guid estateId, public async Task AddMerchant(MerchantDomainEvents.MerchantCreatedEvent domainEvent, CancellationToken cancellationToken) { - EstateManagementContext context = await this.GetContext(domainEvent.EstateId); + using ResolvedDbContext? resolvedContext = this.Resolver.Resolve(EstateManagementDatabaseName, domainEvent.EstateId.ToString()); + await using EstateManagementContext context = resolvedContext.Context; Merchant merchant = new Merchant { @@ -374,7 +377,8 @@ public async Task AddMerchant(MerchantDomainEvents.MerchantCreatedEvent public async Task AddMerchantSchedule(MerchantScheduleDomainEvents.MerchantScheduleCreatedEvent domainEvent, CancellationToken cancellationToken) { - EstateManagementContext context = await this.GetContext(domainEvent.EstateId); + using ResolvedDbContext? resolvedContext = this.Resolver.Resolve(EstateManagementDatabaseName, domainEvent.EstateId.ToString()); + await using EstateManagementContext context = resolvedContext.Context; MerchantSchedule merchantSchedule = new() { @@ -391,7 +395,8 @@ public async Task AddMerchantSchedule(MerchantScheduleDomainEvents.Merch public async Task UpdateMerchant(MerchantNameUpdatedEvent domainEvent, CancellationToken cancellationToken) { - EstateManagementContext context = await this.GetContext(domainEvent.EstateId); + using ResolvedDbContext? resolvedContext = this.Resolver.Resolve(EstateManagementDatabaseName, domainEvent.EstateId.ToString()); + await using EstateManagementContext context = resolvedContext.Context; Result merchantResult = await context.LoadMerchant(domainEvent, cancellationToken); if (merchantResult.IsFailed) @@ -405,7 +410,8 @@ public async Task UpdateMerchant(MerchantNameUpdatedEvent domainEvent, C public async Task AddMerchantAddress(AddressAddedEvent domainEvent, CancellationToken cancellationToken) { - EstateManagementContext context = await this.GetContext(domainEvent.EstateId); + using ResolvedDbContext? resolvedContext = this.Resolver.Resolve(EstateManagementDatabaseName, domainEvent.EstateId.ToString()); + await using EstateManagementContext context = resolvedContext.Context; MerchantAddress merchantAddress = new MerchantAddress { @@ -429,7 +435,8 @@ public async Task AddMerchantAddress(AddressAddedEvent domainEvent, public async Task AddMerchantContact(ContactAddedEvent domainEvent, CancellationToken cancellationToken) { - EstateManagementContext context = await this.GetContext(domainEvent.EstateId); + using ResolvedDbContext? resolvedContext = this.Resolver.Resolve(EstateManagementDatabaseName, domainEvent.EstateId.ToString()); + await using EstateManagementContext context = resolvedContext.Context; MerchantContact merchantContact = new MerchantContact { @@ -448,7 +455,8 @@ public async Task AddMerchantContact(ContactAddedEvent domainEvent, public async Task AddMerchantDevice(DeviceAddedToMerchantEvent domainEvent, CancellationToken cancellationToken) { - EstateManagementContext context = await this.GetContext(domainEvent.EstateId); + using ResolvedDbContext? resolvedContext = this.Resolver.Resolve(EstateManagementDatabaseName, domainEvent.EstateId.ToString()); + await using EstateManagementContext context = resolvedContext.Context; MerchantDevice merchantDevice = new() { MerchantId = domainEvent.MerchantId, @@ -463,7 +471,8 @@ public async Task AddMerchantDevice(DeviceAddedToMerchantEvent domainEve public async Task SwapMerchantDevice(DeviceSwappedForMerchantEvent domainEvent, CancellationToken cancellationToken) { - EstateManagementContext context = await this.GetContext(domainEvent.EstateId); + using ResolvedDbContext? resolvedContext = this.Resolver.Resolve(EstateManagementDatabaseName, domainEvent.EstateId.ToString()); + await using EstateManagementContext context = resolvedContext.Context; Result getOriginalDeviceResult = await context.LoadOriginalMerchantDevice(domainEvent, cancellationToken); if (getOriginalDeviceResult.IsFailed) @@ -481,7 +490,8 @@ public async Task SwapMerchantDevice(DeviceSwappedForMerchantEvent domai public async Task AddMerchantOperator(OperatorAssignedToMerchantEvent domainEvent, CancellationToken cancellationToken) { - EstateManagementContext context = await this.GetContext(domainEvent.EstateId); + using ResolvedDbContext? resolvedContext = this.Resolver.Resolve(EstateManagementDatabaseName, domainEvent.EstateId.ToString()); + await using EstateManagementContext context = resolvedContext.Context; String operatorName = domainEvent.Name; if (String.IsNullOrEmpty(operatorName)) { @@ -512,7 +522,8 @@ public async Task AddMerchantOperator(OperatorAssignedToMerchantEvent do public async Task AddMerchantSecurityUser(SecurityUserAddedToMerchantEvent domainEvent, CancellationToken cancellationToken) { - EstateManagementContext context = await this.GetContext(domainEvent.EstateId); + using ResolvedDbContext? resolvedContext = this.Resolver.Resolve(EstateManagementDatabaseName, domainEvent.EstateId.ToString()); + await using EstateManagementContext context = resolvedContext.Context; MerchantSecurityUser merchantSecurityUser = new MerchantSecurityUser { @@ -528,7 +539,8 @@ public async Task AddMerchantSecurityUser(SecurityUserAddedToMerchantEve public async Task UpdateMerchant(SettlementScheduleChangedEvent domainEvent, CancellationToken cancellationToken) { - EstateManagementContext context = await this.GetContext(domainEvent.EstateId); + using ResolvedDbContext? resolvedContext = this.Resolver.Resolve(EstateManagementDatabaseName, domainEvent.EstateId.ToString()); + await using EstateManagementContext context = resolvedContext.Context; Result merchantResult = await context.LoadMerchant(domainEvent, cancellationToken); if (merchantResult.IsFailed) @@ -541,7 +553,8 @@ public async Task UpdateMerchant(SettlementScheduleChangedEvent domainEv public async Task RemoveOperatorFromMerchant(OperatorRemovedFromMerchantEvent domainEvent, CancellationToken cancellationToken) { - EstateManagementContext context = await this.GetContext(domainEvent.EstateId); + using ResolvedDbContext? resolvedContext = this.Resolver.Resolve(EstateManagementDatabaseName, domainEvent.EstateId.ToString()); + await using EstateManagementContext context = resolvedContext.Context; MerchantOperator merchantOperator = await context.MerchantOperators.SingleOrDefaultAsync(o => o.OperatorId == domainEvent.OperatorId && o.MerchantId == domainEvent.MerchantId, @@ -558,7 +571,8 @@ public async Task RemoveOperatorFromMerchant(OperatorRemovedFromMerchant public async Task RemoveContractFromMerchant(ContractRemovedFromMerchantEvent domainEvent, CancellationToken cancellationToken) { - EstateManagementContext context = await this.GetContext(domainEvent.EstateId); + using ResolvedDbContext? resolvedContext = this.Resolver.Resolve(EstateManagementDatabaseName, domainEvent.EstateId.ToString()); + await using EstateManagementContext context = resolvedContext.Context; MerchantContract merchantContract = await context.MerchantContracts.SingleOrDefaultAsync(o => o.ContractId == domainEvent.ContractId && o.MerchantId == domainEvent.MerchantId, @@ -576,7 +590,8 @@ public async Task RemoveContractFromMerchant(ContractRemovedFromMerchant public async Task UpdateMerchantAddress(MerchantAddressLine1UpdatedEvent domainEvent, CancellationToken cancellationToken) { - EstateManagementContext context = await this.GetContext(domainEvent.EstateId); + using ResolvedDbContext? resolvedContext = this.Resolver.Resolve(EstateManagementDatabaseName, domainEvent.EstateId.ToString()); + await using EstateManagementContext context = resolvedContext.Context; var getMerchantAddressResult = await context.LoadMerchantAddress(domainEvent, cancellationToken); if (getMerchantAddressResult.IsFailed) @@ -590,7 +605,8 @@ public async Task UpdateMerchantAddress(MerchantAddressLine1UpdatedEvent public async Task UpdateMerchantAddress(MerchantAddressLine2UpdatedEvent domainEvent, CancellationToken cancellationToken) { - EstateManagementContext context = await this.GetContext(domainEvent.EstateId); + using ResolvedDbContext? resolvedContext = this.Resolver.Resolve(EstateManagementDatabaseName, domainEvent.EstateId.ToString()); + await using EstateManagementContext context = resolvedContext.Context; var getMerchantAddressResult = await context.LoadMerchantAddress(domainEvent, cancellationToken); if (getMerchantAddressResult.IsFailed) @@ -604,7 +620,8 @@ public async Task UpdateMerchantAddress(MerchantAddressLine2UpdatedEvent public async Task UpdateMerchantAddress(MerchantAddressLine3UpdatedEvent domainEvent, CancellationToken cancellationToken) { - EstateManagementContext context = await this.GetContext(domainEvent.EstateId); + using ResolvedDbContext? resolvedContext = this.Resolver.Resolve(EstateManagementDatabaseName, domainEvent.EstateId.ToString()); + await using EstateManagementContext context = resolvedContext.Context; var getMerchantAddressResult = await context.LoadMerchantAddress(domainEvent, cancellationToken); if (getMerchantAddressResult.IsFailed) @@ -618,7 +635,8 @@ public async Task UpdateMerchantAddress(MerchantAddressLine3UpdatedEvent public async Task UpdateMerchantAddress(MerchantAddressLine4UpdatedEvent domainEvent, CancellationToken cancellationToken) { - EstateManagementContext context = await this.GetContext(domainEvent.EstateId); + using ResolvedDbContext? resolvedContext = this.Resolver.Resolve(EstateManagementDatabaseName, domainEvent.EstateId.ToString()); + await using EstateManagementContext context = resolvedContext.Context; var getMerchantAddressResult = await context.LoadMerchantAddress(domainEvent, cancellationToken); if (getMerchantAddressResult.IsFailed) @@ -632,7 +650,8 @@ public async Task UpdateMerchantAddress(MerchantAddressLine4UpdatedEvent public async Task UpdateMerchantAddress(MerchantCountyUpdatedEvent domainEvent, CancellationToken cancellationToken) { - EstateManagementContext context = await this.GetContext(domainEvent.EstateId); + using ResolvedDbContext? resolvedContext = this.Resolver.Resolve(EstateManagementDatabaseName, domainEvent.EstateId.ToString()); + await using EstateManagementContext context = resolvedContext.Context; var getMerchantAddressResult = await context.LoadMerchantAddress(domainEvent, cancellationToken); if (getMerchantAddressResult.IsFailed) @@ -646,7 +665,8 @@ public async Task UpdateMerchantAddress(MerchantCountyUpdatedEvent domai public async Task UpdateMerchantAddress(MerchantRegionUpdatedEvent domainEvent, CancellationToken cancellationToken) { - EstateManagementContext context = await this.GetContext(domainEvent.EstateId); + using ResolvedDbContext? resolvedContext = this.Resolver.Resolve(EstateManagementDatabaseName, domainEvent.EstateId.ToString()); + await using EstateManagementContext context = resolvedContext.Context; var getMerchantAddressResult = await context.LoadMerchantAddress(domainEvent, cancellationToken); if (getMerchantAddressResult.IsFailed) @@ -660,7 +680,8 @@ public async Task UpdateMerchantAddress(MerchantRegionUpdatedEvent domai public async Task UpdateMerchantAddress(MerchantTownUpdatedEvent domainEvent, CancellationToken cancellationToken) { - EstateManagementContext context = await this.GetContext(domainEvent.EstateId); + using ResolvedDbContext? resolvedContext = this.Resolver.Resolve(EstateManagementDatabaseName, domainEvent.EstateId.ToString()); + await using EstateManagementContext context = resolvedContext.Context; var getMerchantAddressResult = await context.LoadMerchantAddress(domainEvent, cancellationToken); if (getMerchantAddressResult.IsFailed) @@ -674,7 +695,8 @@ public async Task UpdateMerchantAddress(MerchantTownUpdatedEvent domainE public async Task UpdateMerchantAddress(MerchantPostalCodeUpdatedEvent domainEvent, CancellationToken cancellationToken) { - EstateManagementContext context = await this.GetContext(domainEvent.EstateId); + using ResolvedDbContext? resolvedContext = this.Resolver.Resolve(EstateManagementDatabaseName, domainEvent.EstateId.ToString()); + await using EstateManagementContext context = resolvedContext.Context; var getMerchantAddressResult = await context.LoadMerchantAddress(domainEvent, cancellationToken); if (getMerchantAddressResult.IsFailed) @@ -688,7 +710,8 @@ public async Task UpdateMerchantAddress(MerchantPostalCodeUpdatedEvent d public async Task UpdateMerchantContact(MerchantContactNameUpdatedEvent domainEvent, CancellationToken cancellationToken) { - EstateManagementContext context = await this.GetContext(domainEvent.EstateId); + using ResolvedDbContext? resolvedContext = this.Resolver.Resolve(EstateManagementDatabaseName, domainEvent.EstateId.ToString()); + await using EstateManagementContext context = resolvedContext.Context; var getMerchantContactResult = await context.LoadMerchantContact(domainEvent, cancellationToken); if (getMerchantContactResult.IsFailed) @@ -702,7 +725,8 @@ public async Task UpdateMerchantContact(MerchantContactNameUpdatedEvent public async Task UpdateMerchantContact(MerchantContactEmailAddressUpdatedEvent domainEvent, CancellationToken cancellationToken) { - EstateManagementContext context = await this.GetContext(domainEvent.EstateId); + using ResolvedDbContext? resolvedContext = this.Resolver.Resolve(EstateManagementDatabaseName, domainEvent.EstateId.ToString()); + await using EstateManagementContext context = resolvedContext.Context; var getMerchantContactResult = await context.LoadMerchantContact(domainEvent, cancellationToken); if (getMerchantContactResult.IsFailed) @@ -716,7 +740,8 @@ public async Task UpdateMerchantContact(MerchantContactEmailAddressUpdat public async Task UpdateMerchantContact(MerchantContactPhoneNumberUpdatedEvent domainEvent, CancellationToken cancellationToken) { - EstateManagementContext context = await this.GetContext(domainEvent.EstateId); + using ResolvedDbContext? resolvedContext = this.Resolver.Resolve(EstateManagementDatabaseName, domainEvent.EstateId.ToString()); + await using EstateManagementContext context = resolvedContext.Context; var getMerchantContactResult = await context.LoadMerchantContact(domainEvent, cancellationToken); if (getMerchantContactResult.IsFailed) @@ -730,7 +755,8 @@ public async Task UpdateMerchantContact(MerchantContactPhoneNumberUpdate public async Task UpdateMerchantOpeningHours(MerchantOpeningHoursUpdatedEvent domainEvent, CancellationToken cancellationToken) { - EstateManagementContext context = await this.GetContext(domainEvent.EstateId); + using ResolvedDbContext? resolvedContext = this.Resolver.Resolve(EstateManagementDatabaseName, domainEvent.EstateId.ToString()); + await using EstateManagementContext context = resolvedContext.Context; Result getMerchantOpeningHoursResult = await context.LoadMerchantOpeningHours(domainEvent, cancellationToken); if (getMerchantOpeningHoursResult.IsFailed && getMerchantOpeningHoursResult.Status != ResultStatus.NotFound) return ResultHelpers.CreateFailure(getMerchantOpeningHoursResult); @@ -754,7 +780,8 @@ public async Task UpdateMerchantOpeningHours(MerchantOpeningHoursUpdated public async Task UpdateMerchantSchedule(MerchantScheduleDomainEvents.MerchantScheduleMonthUpdatedEvent domainEvent, CancellationToken cancellationToken) { - EstateManagementContext context = await this.GetContext(domainEvent.EstateId); + using ResolvedDbContext? resolvedContext = this.Resolver.Resolve(EstateManagementDatabaseName, domainEvent.EstateId.ToString()); + await using EstateManagementContext context = resolvedContext.Context; Result merchantScheduleResult = await context.LoadMerchantSchedule(domainEvent, cancellationToken); if (merchantScheduleResult.IsFailed) @@ -799,7 +826,8 @@ public async Task UpdateMerchantSchedule(MerchantScheduleDomainEvents.Me public async Task AddContractToMerchant(ContractAddedToMerchantEvent domainEvent, CancellationToken cancellationToken) { - EstateManagementContext context = await this.GetContext(domainEvent.EstateId); + using ResolvedDbContext? resolvedContext = this.Resolver.Resolve(EstateManagementDatabaseName, domainEvent.EstateId.ToString()); + await using EstateManagementContext context = resolvedContext.Context; MerchantContract merchantContract = new MerchantContract { @@ -813,7 +841,8 @@ public async Task AddContractToMerchant(ContractAddedToMerchantEvent dom public async Task UpdateMerchant(MerchantReferenceAllocatedEvent domainEvent, CancellationToken cancellationToken) { - EstateManagementContext context = await this.GetContext(domainEvent.EstateId); + using ResolvedDbContext? resolvedContext = this.Resolver.Resolve(EstateManagementDatabaseName, domainEvent.EstateId.ToString()); + await using EstateManagementContext context = resolvedContext.Context; Result merchantResult = await context.LoadMerchant(domainEvent, cancellationToken); if (merchantResult.IsFailed) @@ -827,7 +856,8 @@ public async Task UpdateMerchant(MerchantReferenceAllocatedEvent domainE public async Task>> GetMerchants(Guid estateId, CancellationToken cancellationToken) { - EstateManagementContext context = await this.GetContext(estateId); + using ResolvedDbContext? resolvedContext = this.Resolver.Resolve(EstateManagementDatabaseName, estateId.ToString()); + await using EstateManagementContext context = resolvedContext.Context; List merchants = await (from m in context.Merchants where m.EstateId == estateId select m).ToListAsync(cancellationToken); List merchantAddresses = await (from a in context.MerchantAddresses where merchants.Select(m => m.MerchantId).Contains(a.MerchantId) select a).ToListAsync(cancellationToken); @@ -867,7 +897,8 @@ public async Task> GetMerchantSchedule(Guid estate Int32 year, CancellationToken cancellationToken) { - EstateManagementContext context = await this.GetContext(estateId); + using ResolvedDbContext? resolvedContext = this.Resolver.Resolve(EstateManagementDatabaseName, estateId.ToString()); + await using EstateManagementContext context = resolvedContext.Context; MerchantSchedule merchantSchedule = await (from s in context.MerchantSchedules where s.EstateId == estateId && @@ -910,7 +941,8 @@ public async Task>> GetMerchantContracts(Guid estateI Guid merchantId, CancellationToken cancellationToken) { - EstateManagementContext context = await this.GetContext(estateId); + using ResolvedDbContext? resolvedContext = this.Resolver.Resolve(EstateManagementDatabaseName, estateId.ToString()); + await using EstateManagementContext context = resolvedContext.Context; var query = await (from c in context.Contracts join cp in context.ContractProducts on c.ContractId equals cp.ContractId @@ -940,7 +972,8 @@ join e in context.Estates on c.EstateId equals e.EstateId public async Task>> GetContracts(Guid estateId, CancellationToken cancellationToken) { - EstateManagementContext context = await this.GetContext(estateId); + using ResolvedDbContext? resolvedContext = this.Resolver.Resolve(EstateManagementDatabaseName, estateId.ToString()); + await using EstateManagementContext context = resolvedContext.Context; var query = await (from c in context.Contracts join cp in context.ContractProducts on c.ContractId equals cp.ContractId into cps @@ -985,12 +1018,6 @@ join e in context.Estates on eo.EstateId equals e.EstateId return Result.Success(ModelFactory.ConvertFrom(estate, estateSecurityUsers, operators)); } - private async Task GetContext(Guid estateId) - { - ResolvedDbContext? resolvedContext = this.Resolver.Resolve(EstateManagementDatabaseName, estateId.ToString()); - return resolvedContext.Context; - } - private ContractModel GetOrCreateMerchantContract(List contracts, Guid estateId, Contract contractData, @@ -1076,7 +1103,8 @@ private void AddProductIfRequired(ContractModel contract, public async Task AddContractProductTransactionFee(ContractDomainEvents.TransactionFeeForProductAddedToContractEvent domainEvent, CancellationToken cancellationToken) { - EstateManagementContext context = await this.GetContext(domainEvent.EstateId); + using ResolvedDbContext? resolvedContext = this.Resolver.Resolve(EstateManagementDatabaseName, domainEvent.EstateId.ToString()); + await using EstateManagementContext context = resolvedContext.Context; ContractProductTransactionFee contractProductTransactionFee = new ContractProductTransactionFee { @@ -1096,7 +1124,8 @@ public async Task AddContractProductTransactionFee(ContractDomainEvents. public async Task AddEstate(EstateDomainEvents.EstateCreatedEvent domainEvent, CancellationToken cancellationToken) { - EstateManagementContext context = await this.GetContext(domainEvent.EstateId); + using ResolvedDbContext? resolvedContext = this.Resolver.Resolve(EstateManagementDatabaseName, domainEvent.EstateId.ToString()); + await using EstateManagementContext context = resolvedContext.Context; // Add the estate to the read model Database.Entities.Estate estate = new Database.Entities.Estate @@ -1112,7 +1141,8 @@ public async Task AddEstate(EstateDomainEvents.EstateCreatedEvent domain public async Task AddEstateSecurityUser(EstateDomainEvents.SecurityUserAddedToEstateEvent domainEvent, CancellationToken cancellationToken) { - EstateManagementContext context = await this.GetContext(domainEvent.EstateId); + using ResolvedDbContext? resolvedContext = this.Resolver.Resolve(EstateManagementDatabaseName, domainEvent.EstateId.ToString()); + await using EstateManagementContext context = resolvedContext.Context; EstateSecurityUser estateSecurityUser = new EstateSecurityUser { @@ -1129,7 +1159,8 @@ public async Task AddEstateSecurityUser(EstateDomainEvents.SecurityUserA public async Task AddProductDetailsToTransaction(TransactionDomainEvents.ProductDetailsAddedToTransactionEvent domainEvent, CancellationToken cancellationToken) { - EstateManagementContext context = await this.GetContext(domainEvent.EstateId); + using ResolvedDbContext? resolvedContext = this.Resolver.Resolve(EstateManagementDatabaseName, domainEvent.EstateId.ToString()); + await using EstateManagementContext context = resolvedContext.Context; var getTransactionResult = await context.LoadTransaction(domainEvent, cancellationToken); if (getTransactionResult.IsFailed) @@ -1150,7 +1181,8 @@ public async Task AddProductDetailsToTransaction(TransactionDomainEvents public async Task AddSettledMerchantFeeToSettlement(TransactionDomainEvents.SettledMerchantFeeAddedToTransactionEvent domainEvent, CancellationToken cancellationToken) { - EstateManagementContext context = await this.GetContext(domainEvent.EstateId); + using ResolvedDbContext? resolvedContext = this.Resolver.Resolve(EstateManagementDatabaseName, domainEvent.EstateId.ToString()); + await using EstateManagementContext context = resolvedContext.Context; MerchantSettlementFee merchantSettlementFee = new MerchantSettlementFee { @@ -1170,7 +1202,8 @@ public async Task AddSettledMerchantFeeToSettlement(TransactionDomainEve public async Task AddSourceDetailsToTransaction(TransactionDomainEvents.TransactionSourceAddedToTransactionEvent domainEvent, CancellationToken cancellationToken) { - EstateManagementContext context = await this.GetContext(domainEvent.EstateId); + using ResolvedDbContext? resolvedContext = this.Resolver.Resolve(EstateManagementDatabaseName, domainEvent.EstateId.ToString()); + await using EstateManagementContext context = resolvedContext.Context; var getTransactionResult = await context.LoadTransaction(domainEvent, cancellationToken); if (getTransactionResult.IsFailed) @@ -1184,7 +1217,8 @@ public async Task AddSourceDetailsToTransaction(TransactionDomainEvents. public async Task CompleteReconciliation(ReconciliationDomainEvents.ReconciliationHasCompletedEvent domainEvent, CancellationToken cancellationToken) { - EstateManagementContext context = await this.GetContext(domainEvent.EstateId); + using ResolvedDbContext? resolvedContext = this.Resolver.Resolve(EstateManagementDatabaseName, domainEvent.EstateId.ToString()); + await using EstateManagementContext context = resolvedContext.Context; var getReconcilationResult = await context.LoadReconcilation(domainEvent, cancellationToken); if (getReconcilationResult.IsFailed) @@ -1198,7 +1232,8 @@ public async Task CompleteReconciliation(ReconciliationDomainEvents.Reco public async Task CompleteTransaction(TransactionDomainEvents.TransactionHasBeenCompletedEvent domainEvent, CancellationToken cancellationToken) { - EstateManagementContext context = await this.GetContext(domainEvent.EstateId); + using ResolvedDbContext? resolvedContext = this.Resolver.Resolve(EstateManagementDatabaseName, domainEvent.EstateId.ToString()); + await using EstateManagementContext context = resolvedContext.Context; var getTransactionResult = await context.LoadTransaction(domainEvent, cancellationToken); if (getTransactionResult.IsFailed) @@ -1212,7 +1247,8 @@ public async Task CompleteTransaction(TransactionDomainEvents.Transactio public async Task CreateFloat(FloatDomainEvents.FloatCreatedForContractProductEvent domainEvent, CancellationToken cancellationToken) { - EstateManagementContext context = await this.GetContext(domainEvent.EstateId); + using ResolvedDbContext? resolvedContext = this.Resolver.Resolve(EstateManagementDatabaseName, domainEvent.EstateId.ToString()); + await using EstateManagementContext context = resolvedContext.Context; Database.Entities.Float floatRecord = new Database.Entities.Float { @@ -1229,7 +1265,8 @@ public async Task CreateFloat(FloatDomainEvents.FloatCreatedForContractP public async Task CreateFloatActivity(FloatDomainEvents.FloatCreditPurchasedEvent domainEvent, CancellationToken cancellationToken) { - EstateManagementContext context = await this.GetContext(domainEvent.EstateId); + using ResolvedDbContext? resolvedContext = this.Resolver.Resolve(EstateManagementDatabaseName, domainEvent.EstateId.ToString()); + await using EstateManagementContext context = resolvedContext.Context; FloatActivity floatActivity = new FloatActivity { @@ -1247,7 +1284,8 @@ public async Task CreateFloatActivity(FloatDomainEvents.FloatCreditPurch public async Task CreateFloatActivity(FloatDomainEvents.FloatDecreasedByTransactionEvent domainEvent, CancellationToken cancellationToken) { - EstateManagementContext context = await this.GetContext(domainEvent.EstateId); + using ResolvedDbContext? resolvedContext = this.Resolver.Resolve(EstateManagementDatabaseName, domainEvent.EstateId.ToString()); + await using EstateManagementContext context = resolvedContext.Context; var getTransactionResult = await context.LoadTransaction(domainEvent, cancellationToken); if (getTransactionResult.IsFailed) @@ -1270,7 +1308,8 @@ public async Task CreateFloatActivity(FloatDomainEvents.FloatDecreasedBy public async Task CreateReadModel(EstateDomainEvents.EstateCreatedEvent domainEvent, CancellationToken cancellationToken) { - EstateManagementContext context = await this.GetContext(domainEvent.EstateId); + using ResolvedDbContext? resolvedContext = this.Resolver.Resolve(EstateManagementDatabaseName, domainEvent.EstateId.ToString()); + await using EstateManagementContext context = resolvedContext.Context; Logger.LogInformation($"About to run migrations on Read Model database for estate [{domainEvent.EstateId}]"); @@ -1283,7 +1322,8 @@ public async Task CreateReadModel(EstateDomainEvents.EstateCreatedEvent public async Task CreateSettlement(SettlementDomainEvents.SettlementCreatedForDateEvent domainEvent, CancellationToken cancellationToken) { - EstateManagementContext context = await this.GetContext(domainEvent.EstateId); + using ResolvedDbContext? resolvedContext = this.Resolver.Resolve(EstateManagementDatabaseName, domainEvent.EstateId.ToString()); + await using EstateManagementContext context = resolvedContext.Context; Database.Entities.Settlement settlement = new Database.Entities.Settlement { @@ -1301,7 +1341,8 @@ public async Task CreateSettlement(SettlementDomainEvents.SettlementCrea public async Task DisableContractProductTransactionFee(ContractDomainEvents.TransactionFeeForProductDisabledEvent domainEvent, CancellationToken cancellationToken) { - EstateManagementContext context = await this.GetContext(domainEvent.EstateId); + using ResolvedDbContext? resolvedContext = this.Resolver.Resolve(EstateManagementDatabaseName, domainEvent.EstateId.ToString()); + await using EstateManagementContext context = resolvedContext.Context; Result loadContractProductTransactionFeeResult = await context.LoadContractProductTransactionFee(domainEvent, cancellationToken); if (loadContractProductTransactionFeeResult.IsFailed) @@ -1316,7 +1357,8 @@ public async Task DisableContractProductTransactionFee(ContractDomainEve public async Task MarkMerchantFeeAsSettled(SettlementDomainEvents.MerchantFeeSettledEvent domainEvent, CancellationToken cancellationToken) { - EstateManagementContext context = await this.GetContext(domainEvent.EstateId); + using ResolvedDbContext? resolvedContext = this.Resolver.Resolve(EstateManagementDatabaseName, domainEvent.EstateId.ToString()); + await using EstateManagementContext context = resolvedContext.Context; MerchantSettlementFee merchantFee = await context.MerchantSettlementFees.Where(m => m.MerchantId == domainEvent.MerchantId && @@ -1336,7 +1378,8 @@ public async Task MarkMerchantFeeAsSettled(SettlementDomainEvents.Mercha public async Task MarkSettlementAsCompleted(SettlementDomainEvents.SettlementCompletedEvent domainEvent, CancellationToken cancellationToken) { - EstateManagementContext context = await this.GetContext(domainEvent.EstateId); + using ResolvedDbContext? resolvedContext = this.Resolver.Resolve(EstateManagementDatabaseName, domainEvent.EstateId.ToString()); + await using EstateManagementContext context = resolvedContext.Context; var getSettlementResult = await context.LoadSettlement(domainEvent, cancellationToken); if (getSettlementResult.IsFailed) @@ -1349,7 +1392,8 @@ public async Task MarkSettlementAsCompleted(SettlementDomainEvents.Settl public async Task MarkSettlementAsProcessingStarted(SettlementDomainEvents.SettlementProcessingStartedEvent domainEvent, CancellationToken cancellationToken) { - EstateManagementContext context = await this.GetContext(domainEvent.EstateId); + using ResolvedDbContext? resolvedContext = this.Resolver.Resolve(EstateManagementDatabaseName, domainEvent.EstateId.ToString()); + await using EstateManagementContext context = resolvedContext.Context; var getSettlementResult = await context.LoadSettlement(domainEvent, cancellationToken); if (getSettlementResult.IsFailed) @@ -1371,7 +1415,8 @@ public async Task MarkSettlementAsProcessingStarted(SettlementDomainEven public async Task RecordTransactionAdditionalRequestData(TransactionDomainEvents.AdditionalRequestDataRecordedEvent domainEvent, CancellationToken cancellationToken) { - EstateManagementContext context = await this.GetContext(domainEvent.EstateId); + using ResolvedDbContext? resolvedContext = this.Resolver.Resolve(EstateManagementDatabaseName, domainEvent.EstateId.ToString()); + await using EstateManagementContext context = resolvedContext.Context; TransactionAdditionalRequestData additionalRequestData = new TransactionAdditionalRequestData { @@ -1414,7 +1459,8 @@ public async Task RecordTransactionAdditionalRequestData(TransactionDoma public async Task RecordTransactionAdditionalResponseData(TransactionDomainEvents.AdditionalResponseDataRecordedEvent domainEvent, CancellationToken cancellationToken) { - EstateManagementContext context = await this.GetContext(domainEvent.EstateId); + using ResolvedDbContext? resolvedContext = this.Resolver.Resolve(EstateManagementDatabaseName, domainEvent.EstateId.ToString()); + await using EstateManagementContext context = resolvedContext.Context; TransactionAdditionalResponseData additionalResponseData = new TransactionAdditionalResponseData { @@ -1443,7 +1489,8 @@ public async Task RecordTransactionAdditionalResponseData(TransactionDom public async Task SetTransactionAmount(TransactionDomainEvents.AdditionalRequestDataRecordedEvent domainEvent, CancellationToken cancellationToken) { - EstateManagementContext context = await this.GetContext(domainEvent.EstateId); + using ResolvedDbContext? resolvedContext = this.Resolver.Resolve(EstateManagementDatabaseName, domainEvent.EstateId.ToString()); + await using EstateManagementContext context = resolvedContext.Context; var getTransactionResult = await context.LoadTransaction(domainEvent, cancellationToken); if (getTransactionResult.IsFailed) @@ -1470,7 +1517,8 @@ public async Task SetTransactionAmount(TransactionDomainEvents.Additiona public async Task StartReconciliation(ReconciliationDomainEvents.ReconciliationHasStartedEvent domainEvent, CancellationToken cancellationToken) { - EstateManagementContext context = await this.GetContext(domainEvent.EstateId); + using ResolvedDbContext? resolvedContext = this.Resolver.Resolve(EstateManagementDatabaseName, domainEvent.EstateId.ToString()); + await using EstateManagementContext context = resolvedContext.Context; Database.Entities.Reconciliation reconciliation = new Database.Entities.Reconciliation { @@ -1488,7 +1536,8 @@ public async Task StartReconciliation(ReconciliationDomainEvents.Reconci public async Task StartTransaction(TransactionDomainEvents.TransactionHasStartedEvent domainEvent, CancellationToken cancellationToken) { - EstateManagementContext context = await this.GetContext(domainEvent.EstateId); + using ResolvedDbContext? resolvedContext = this.Resolver.Resolve(EstateManagementDatabaseName, domainEvent.EstateId.ToString()); + await using EstateManagementContext context = resolvedContext.Context; Database.Entities.Transaction t = new Database.Entities.Transaction { @@ -1516,7 +1565,8 @@ public async Task StartTransaction(TransactionDomainEvents.TransactionHa public async Task UpdateEstate(EstateDomainEvents.EstateReferenceAllocatedEvent domainEvent, CancellationToken cancellationToken) { - EstateManagementContext context = await this.GetContext(domainEvent.EstateId); + using ResolvedDbContext? resolvedContext = this.Resolver.Resolve(EstateManagementDatabaseName, domainEvent.EstateId.ToString()); + await using EstateManagementContext context = resolvedContext.Context; var getEstateResult = await context.LoadEstate(domainEvent, cancellationToken); if (getEstateResult.IsFailed) @@ -1530,7 +1580,8 @@ public async Task UpdateEstate(EstateDomainEvents.EstateReferenceAllocat public async Task UpdateMerchant(TransactionDomainEvents.TransactionHasBeenCompletedEvent domainEvent, CancellationToken cancellationToken) { - EstateManagementContext context = await this.GetContext(domainEvent.EstateId); + using ResolvedDbContext? resolvedContext = this.Resolver.Resolve(EstateManagementDatabaseName, domainEvent.EstateId.ToString()); + await using EstateManagementContext context = resolvedContext.Context; Result merchantResult = await context.LoadMerchant(domainEvent, cancellationToken); if (merchantResult.IsFailed) @@ -1549,7 +1600,8 @@ public async Task UpdateMerchant(TransactionDomainEvents.TransactionHasB public async Task UpdateReconciliationOverallTotals(ReconciliationDomainEvents.OverallTotalsRecordedEvent domainEvent, CancellationToken cancellationToken) { - EstateManagementContext context = await this.GetContext(domainEvent.EstateId); + using ResolvedDbContext? resolvedContext = this.Resolver.Resolve(EstateManagementDatabaseName, domainEvent.EstateId.ToString()); + await using EstateManagementContext context = resolvedContext.Context; var getReconcilationResult = await context.LoadReconcilation(domainEvent, cancellationToken); if (getReconcilationResult.IsFailed) @@ -1564,7 +1616,8 @@ public async Task UpdateReconciliationOverallTotals(ReconciliationDomain public async Task UpdateReconciliationStatus(ReconciliationDomainEvents.ReconciliationHasBeenLocallyAuthorisedEvent domainEvent, CancellationToken cancellationToken) { - EstateManagementContext context = await this.GetContext(domainEvent.EstateId); + using ResolvedDbContext? resolvedContext = this.Resolver.Resolve(EstateManagementDatabaseName, domainEvent.EstateId.ToString()); + await using EstateManagementContext context = resolvedContext.Context; var getReconcilationResult = await context.LoadReconcilation(domainEvent, cancellationToken); if (getReconcilationResult.IsFailed) @@ -1580,7 +1633,8 @@ public async Task UpdateReconciliationStatus(ReconciliationDomainEvents. public async Task UpdateReconciliationStatus(ReconciliationDomainEvents.ReconciliationHasBeenLocallyDeclinedEvent domainEvent, CancellationToken cancellationToken) { - EstateManagementContext context = await this.GetContext(domainEvent.EstateId); + using ResolvedDbContext? resolvedContext = this.Resolver.Resolve(EstateManagementDatabaseName, domainEvent.EstateId.ToString()); + await using EstateManagementContext context = resolvedContext.Context; var getReconcilationResult = await context.LoadReconcilation(domainEvent, cancellationToken); if (getReconcilationResult.IsFailed) @@ -1596,7 +1650,8 @@ public async Task UpdateReconciliationStatus(ReconciliationDomainEvents. public async Task UpdateTransactionAuthorisation(TransactionDomainEvents.TransactionHasBeenLocallyAuthorisedEvent domainEvent, CancellationToken cancellationToken) { - EstateManagementContext context = await this.GetContext(domainEvent.EstateId); + using ResolvedDbContext? resolvedContext = this.Resolver.Resolve(EstateManagementDatabaseName, domainEvent.EstateId.ToString()); + await using EstateManagementContext context = resolvedContext.Context; var getTransactionResult = await context.LoadTransaction(domainEvent, cancellationToken); if (getTransactionResult.IsFailed) @@ -1613,7 +1668,8 @@ public async Task UpdateTransactionAuthorisation(TransactionDomainEvents public async Task UpdateTransactionAuthorisation(TransactionDomainEvents.TransactionHasBeenLocallyDeclinedEvent domainEvent, CancellationToken cancellationToken) { - EstateManagementContext context = await this.GetContext(domainEvent.EstateId); + using ResolvedDbContext? resolvedContext = this.Resolver.Resolve(EstateManagementDatabaseName, domainEvent.EstateId.ToString()); + await using EstateManagementContext context = resolvedContext.Context; var getTransactionResult = await context.LoadTransaction(domainEvent, cancellationToken); if (getTransactionResult.IsFailed) @@ -1629,7 +1685,8 @@ public async Task UpdateTransactionAuthorisation(TransactionDomainEvents public async Task UpdateTransactionAuthorisation(TransactionDomainEvents.TransactionAuthorisedByOperatorEvent domainEvent, CancellationToken cancellationToken) { - EstateManagementContext context = await this.GetContext(domainEvent.EstateId); + using ResolvedDbContext? resolvedContext = this.Resolver.Resolve(EstateManagementDatabaseName, domainEvent.EstateId.ToString()); + await using EstateManagementContext context = resolvedContext.Context; var getTransactionResult = await context.LoadTransaction(domainEvent, cancellationToken); if (getTransactionResult.IsFailed) @@ -1646,7 +1703,8 @@ public async Task UpdateTransactionAuthorisation(TransactionDomainEvents public async Task UpdateTransactionAuthorisation(TransactionDomainEvents.TransactionDeclinedByOperatorEvent domainEvent, CancellationToken cancellationToken) { - EstateManagementContext context = await this.GetContext(domainEvent.EstateId); + using ResolvedDbContext? resolvedContext = this.Resolver.Resolve(EstateManagementDatabaseName, domainEvent.EstateId.ToString()); + await using EstateManagementContext context = resolvedContext.Context; var getTransactionResult = await context.LoadTransaction(domainEvent, cancellationToken); if (getTransactionResult.IsFailed) @@ -1662,7 +1720,8 @@ public async Task UpdateTransactionAuthorisation(TransactionDomainEvents public async Task>> GetOperators(Guid estateId, CancellationToken cancellationToken) { - EstateManagementContext context = await this.GetContext(estateId); + using ResolvedDbContext? resolvedContext = this.Resolver.Resolve(EstateManagementDatabaseName, estateId.ToString()); + await using EstateManagementContext context = resolvedContext.Context; Database.Entities.Estate estate = await context.Estates.SingleOrDefaultAsync(e => e.EstateId == estateId, cancellationToken: cancellationToken); List operators = await (from o in context.Operators where o.EstateId == estate.EstateId select o).ToListAsync(cancellationToken); @@ -1685,7 +1744,8 @@ public async Task UpdateTransactionAuthorisation(TransactionDomainEvents public async Task UpdateOperator(OperatorDomainEvents.OperatorNameUpdatedEvent domainEvent, CancellationToken cancellationToken) { - EstateManagementContext context = await this.GetContext(domainEvent.EstateId); + using ResolvedDbContext? resolvedContext = this.Resolver.Resolve(EstateManagementDatabaseName, domainEvent.EstateId.ToString()); + await using EstateManagementContext context = resolvedContext.Context; Result operatorResult = await context.LoadOperator(domainEvent, cancellationToken); if (operatorResult.IsFailed) @@ -1698,7 +1758,8 @@ public async Task UpdateOperator(OperatorDomainEvents.OperatorNameUpdate public async Task UpdateOperator(OperatorDomainEvents.OperatorRequireCustomMerchantNumberChangedEvent domainEvent, CancellationToken cancellationToken) { - EstateManagementContext context = await this.GetContext(domainEvent.EstateId); + using ResolvedDbContext? resolvedContext = this.Resolver.Resolve(EstateManagementDatabaseName, domainEvent.EstateId.ToString()); + await using EstateManagementContext context = resolvedContext.Context; Result operatorResult = await context.LoadOperator(domainEvent, cancellationToken); if (operatorResult.IsFailed) @@ -1712,7 +1773,8 @@ public async Task UpdateOperator(OperatorDomainEvents.OperatorRequireCus public async Task UpdateOperator(OperatorDomainEvents.OperatorRequireCustomTerminalNumberChangedEvent domainEvent, CancellationToken cancellationToken) { - EstateManagementContext context = await this.GetContext(domainEvent.EstateId); + using ResolvedDbContext? resolvedContext = this.Resolver.Resolve(EstateManagementDatabaseName, domainEvent.EstateId.ToString()); + await using EstateManagementContext context = resolvedContext.Context; Result operatorResult = await context.LoadOperator(domainEvent, cancellationToken); if (operatorResult.IsFailed) @@ -1726,7 +1788,8 @@ public async Task UpdateOperator(OperatorDomainEvents.OperatorRequireCus public async Task AddOperator(OperatorDomainEvents.OperatorCreatedEvent domainEvent, CancellationToken cancellationToken) { - EstateManagementContext context = await this.GetContext(domainEvent.EstateId); + using ResolvedDbContext? resolvedContext = this.Resolver.Resolve(EstateManagementDatabaseName, domainEvent.EstateId.ToString()); + await using EstateManagementContext context = resolvedContext.Context; Database.Entities.Operator @operator = new Database.Entities.Operator { @@ -1744,7 +1807,8 @@ public async Task AddOperator(OperatorDomainEvents.OperatorCreatedEvent public async Task AddContract(ContractDomainEvents.ContractCreatedEvent domainEvent, CancellationToken cancellationToken) { - EstateManagementContext context = await this.GetContext(domainEvent.EstateId); + using ResolvedDbContext? resolvedContext = this.Resolver.Resolve(EstateManagementDatabaseName, domainEvent.EstateId.ToString()); + await using EstateManagementContext context = resolvedContext.Context; Contract contract = new Contract { @@ -1761,7 +1825,8 @@ public async Task AddContract(ContractDomainEvents.ContractCreatedEvent public async Task AddContractProduct(ContractDomainEvents.VariableValueProductAddedToContractEvent domainEvent, CancellationToken cancellationToken) { - EstateManagementContext context = await this.GetContext(domainEvent.EstateId); + using ResolvedDbContext? resolvedContext = this.Resolver.Resolve(EstateManagementDatabaseName, domainEvent.EstateId.ToString()); + await using EstateManagementContext context = resolvedContext.Context; ContractProduct contractProduct = new ContractProduct { @@ -1780,7 +1845,8 @@ public async Task AddContractProduct(ContractDomainEvents.VariableValueP public async Task AddContractProduct(ContractDomainEvents.FixedValueProductAddedToContractEvent domainEvent, CancellationToken cancellationToken) { - EstateManagementContext context = await this.GetContext(domainEvent.EstateId); + using ResolvedDbContext? resolvedContext = this.Resolver.Resolve(EstateManagementDatabaseName, domainEvent.EstateId.ToString()); + await using EstateManagementContext context = resolvedContext.Context; ContractProduct contractProduct = new ContractProduct { @@ -1800,7 +1866,8 @@ public async Task AddContractProduct(ContractDomainEvents.FixedValueProd public async Task MarkStatementAsGenerated(StatementGeneratedEvent domainEvent, CancellationToken cancellationToken) { - EstateManagementContext context = await this.GetContext(domainEvent.EstateId); + using ResolvedDbContext? resolvedContext = this.Resolver.Resolve(EstateManagementDatabaseName, domainEvent.EstateId.ToString()); + await using EstateManagementContext context = resolvedContext.Context; var getLoadStatementHeaderResult = await context.LoadStatementHeader(domainEvent, cancellationToken); if (getLoadStatementHeaderResult.IsFailed) @@ -1814,7 +1881,8 @@ public async Task MarkStatementAsGenerated(StatementGeneratedEvent domai public async Task CreateStatement(StatementCreatedEvent domainEvent, CancellationToken cancellationToken) { - EstateManagementContext context = await this.GetContext(domainEvent.EstateId); + using ResolvedDbContext? resolvedContext = this.Resolver.Resolve(EstateManagementDatabaseName, domainEvent.EstateId.ToString()); + await using EstateManagementContext context = resolvedContext.Context; StatementHeader header = new StatementHeader { @@ -1832,7 +1900,8 @@ public async Task CreateStatement(StatementCreatedEvent domainEvent, public async Task AddFile(FileCreatedEvent domainEvent, CancellationToken cancellationToken) { - EstateManagementContext context = await this.GetContext(domainEvent.EstateId); + using ResolvedDbContext? resolvedContext = this.Resolver.Resolve(EstateManagementDatabaseName, domainEvent.EstateId.ToString()); + await using EstateManagementContext context = resolvedContext.Context; File file = new File { @@ -1855,7 +1924,8 @@ public async Task AddFile(FileCreatedEvent domainEvent, public async Task AddFileImportLog(ImportLogCreatedEvent domainEvent, CancellationToken cancellationToken) { - EstateManagementContext context = await this.GetContext(domainEvent.EstateId); + using ResolvedDbContext? resolvedContext = this.Resolver.Resolve(EstateManagementDatabaseName, domainEvent.EstateId.ToString()); + await using EstateManagementContext context = resolvedContext.Context; FileImportLog fileImportLog = new FileImportLog { @@ -1873,7 +1943,8 @@ public async Task AddFileImportLog(ImportLogCreatedEvent domainEvent, public async Task AddFileLineToFile(FileLineAddedEvent domainEvent, CancellationToken cancellationToken) { - EstateManagementContext context = await this.GetContext(domainEvent.EstateId); + using ResolvedDbContext? resolvedContext = this.Resolver.Resolve(EstateManagementDatabaseName, domainEvent.EstateId.ToString()); + await using EstateManagementContext context = resolvedContext.Context; FileLine fileLine = new FileLine { @@ -1891,7 +1962,8 @@ public async Task AddFileLineToFile(FileLineAddedEvent domainEvent, public async Task AddFileToImportLog(FileAddedToImportLogEvent domainEvent, CancellationToken cancellationToken) { - EstateManagementContext context = await this.GetContext(domainEvent.EstateId); + using ResolvedDbContext? resolvedContext = this.Resolver.Resolve(EstateManagementDatabaseName, domainEvent.EstateId.ToString()); + await using EstateManagementContext context = resolvedContext.Context; FileImportLogFile fileImportLogFile = new FileImportLogFile { @@ -1914,7 +1986,8 @@ public async Task AddFileToImportLog(FileAddedToImportLogEvent domainEve public async Task UpdateFileAsComplete(FileProcessingCompletedEvent domainEvent, CancellationToken cancellationToken) { - EstateManagementContext context = await this.GetContext(domainEvent.EstateId); + using ResolvedDbContext? resolvedContext = this.Resolver.Resolve(EstateManagementDatabaseName, domainEvent.EstateId.ToString()); + await using EstateManagementContext context = resolvedContext.Context; var getFileResult = await context.LoadFile(domainEvent, cancellationToken); if (getFileResult.IsFailed) @@ -1929,7 +2002,8 @@ public async Task UpdateFileAsComplete(FileProcessingCompletedEvent doma public async Task UpdateFileLine(FileLineProcessingSuccessfulEvent domainEvent, CancellationToken cancellationToken) { - EstateManagementContext context = await this.GetContext(domainEvent.EstateId); + using ResolvedDbContext? resolvedContext = this.Resolver.Resolve(EstateManagementDatabaseName, domainEvent.EstateId.ToString()); + await using EstateManagementContext context = resolvedContext.Context; return await this.UpdateFileLineStatus(context, domainEvent.FileId, @@ -1962,7 +2036,8 @@ private async Task UpdateFileLineStatus(EstateManagementContext context, public async Task UpdateFileLine(FileLineProcessingFailedEvent domainEvent, CancellationToken cancellationToken) { - EstateManagementContext context = await this.GetContext(domainEvent.EstateId); + using ResolvedDbContext? resolvedContext = this.Resolver.Resolve(EstateManagementDatabaseName, domainEvent.EstateId.ToString()); + await using EstateManagementContext context = resolvedContext.Context; return await this.UpdateFileLineStatus(context, domainEvent.FileId, @@ -1975,7 +2050,8 @@ public async Task UpdateFileLine(FileLineProcessingFailedEvent domainEve public async Task UpdateFileLine(FileLineProcessingIgnoredEvent domainEvent, CancellationToken cancellationToken) { - EstateManagementContext context = await this.GetContext(domainEvent.EstateId); + using ResolvedDbContext? resolvedContext = this.Resolver.Resolve(EstateManagementDatabaseName, domainEvent.EstateId.ToString()); + await using EstateManagementContext context = resolvedContext.Context; return await this.UpdateFileLineStatus(context, domainEvent.FileId, @@ -1988,7 +2064,8 @@ public async Task UpdateFileLine(FileLineProcessingIgnoredEvent domainEv public async Task AddPendingMerchantFeeToSettlement(SettlementDomainEvents.MerchantFeeAddedPendingSettlementEvent domainEvent, CancellationToken cancellationToken) { - EstateManagementContext context = await this.GetContext(domainEvent.EstateId); + using ResolvedDbContext? resolvedContext = this.Resolver.Resolve(EstateManagementDatabaseName, domainEvent.EstateId.ToString()); + await using EstateManagementContext context = resolvedContext.Context; MerchantSettlementFee merchantSettlementFee = new MerchantSettlementFee { @@ -2012,7 +2089,8 @@ public async Task> GetSettlement(Guid estateId, Guid settlementId, CancellationToken cancellationToken) { - EstateManagementContext context = await this.GetContext(estateId); + using ResolvedDbContext? resolvedContext = this.Resolver.Resolve(EstateManagementDatabaseName, estateId.ToString()); + await using EstateManagementContext context = resolvedContext.Context; IQueryable query = context.SettlementsView.Where(t => t.EstateId == estateId && t.SettlementId == settlementId && t.MerchantId == merchantId).AsQueryable(); @@ -2057,7 +2135,8 @@ public async Task>> GetSettlements(Guid estateId, String endDate, CancellationToken cancellationToken) { - EstateManagementContext context = await this.GetContext(estateId); + using ResolvedDbContext? resolvedContext = this.Resolver.Resolve(EstateManagementDatabaseName, estateId.ToString()); + await using EstateManagementContext context = resolvedContext.Context; DateTime queryStartDate = DateTime.ParseExact(startDate, "yyyyMMdd", null); DateTime queryEndDate = DateTime.ParseExact(endDate, "yyyyMMdd", null); @@ -2099,7 +2178,8 @@ public async Task RecordTransactionTimings(TransactionDomainEvents.Trans TimeSpan transactionTime = totalTime.Subtract(operatorCommunicationsTime); // Load this information to the database - EstateManagementContext context = await this.GetContext(domainEvent.EstateId); + using ResolvedDbContext? resolvedContext = this.Resolver.Resolve(EstateManagementDatabaseName, domainEvent.EstateId.ToString()); + await using EstateManagementContext context = resolvedContext.Context; TransactionTimings timings = new() { TransactionStartedDateTime = domainEvent.TransactionStartedDateTime, @@ -2118,7 +2198,8 @@ public async Task RecordTransactionTimings(TransactionDomainEvents.Trans public async Task AddTransactionToStatement(MerchantStatementForDateDomainEvents.TransactionAddedToStatementForDateEvent domainEvent, CancellationToken cancellationToken) { // Load this information to the database - EstateManagementContext context = await this.GetContext(domainEvent.EstateId); + using ResolvedDbContext? resolvedContext = this.Resolver.Resolve(EstateManagementDatabaseName, domainEvent.EstateId.ToString()); + await using EstateManagementContext context = resolvedContext.Context; // Find the corresponding transaction Result transactionResult = await context.LoadTransaction(domainEvent, cancellationToken); @@ -2151,7 +2232,8 @@ public async Task AddSettledFeeToStatement(MerchantStatementForDateDomai CancellationToken cancellationToken) { // Load this information to the database - EstateManagementContext context = await this.GetContext(domainEvent.EstateId); + using ResolvedDbContext? resolvedContext = this.Resolver.Resolve(EstateManagementDatabaseName, domainEvent.EstateId.ToString()); + await using EstateManagementContext context = resolvedContext.Context; // Find the corresponding transaction var getTransactionResult = await context.LoadTransaction(domainEvent, cancellationToken); @@ -2183,7 +2265,8 @@ public async Task AddSettledFeeToStatement(MerchantStatementForDateDomai public async Task AddEstateOperator(EstateDomainEvents.OperatorAddedToEstateEvent domainEvent, CancellationToken cancellationToken) { // Load this information to the database - EstateManagementContext context = await this.GetContext(domainEvent.EstateId); + using ResolvedDbContext? resolvedContext = this.Resolver.Resolve(EstateManagementDatabaseName, domainEvent.EstateId.ToString()); + await using EstateManagementContext context = resolvedContext.Context; var estateOperator = await context.EstateOperators.SingleOrDefaultAsync(eo => eo.EstateId == domainEvent.EstateId && eo.OperatorId == domainEvent.OperatorId, cancellationToken); @@ -2201,7 +2284,8 @@ public async Task AddEstateOperator(EstateDomainEvents.OperatorAddedToEs public async Task RemoveOperatorFromEstate(EstateDomainEvents.OperatorRemovedFromEstateEvent domainEvent, CancellationToken cancellationToken) { // Load this information to the database - EstateManagementContext context = await this.GetContext(domainEvent.EstateId); + using ResolvedDbContext? resolvedContext = this.Resolver.Resolve(EstateManagementDatabaseName, domainEvent.EstateId.ToString()); + await using EstateManagementContext context = resolvedContext.Context; var estateOperator = await context.EstateOperators.SingleOrDefaultAsync(eo => eo.EstateId == domainEvent.EstateId && eo.OperatorId == domainEvent.OperatorId, cancellationToken); diff --git a/TransactionProcessor.Tests/RepositoryTests/TransactionProcessorReadModelRepositoryTests.cs b/TransactionProcessor.Tests/RepositoryTests/TransactionProcessorReadModelRepositoryTests.cs new file mode 100644 index 00000000..508a5d73 --- /dev/null +++ b/TransactionProcessor.Tests/RepositoryTests/TransactionProcessorReadModelRepositoryTests.cs @@ -0,0 +1,84 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Data.Sqlite; +using Moq; +using Shared.EntityFramework; +using Shouldly; +using System; +using System.Data.Common; +using System.Threading; +using System.Threading.Tasks; +using TransactionProcessor.Database.Contexts; +using TransactionProcessor.Database.Entities; +using TransactionProcessor.Repository; +using Xunit; + +namespace TransactionProcessor.Tests.RepositoryTests +{ + public class TransactionProcessorReadModelRepositoryTests + { + private static (EstateManagementContext Context, DbConnection Connection) CreateContext() + { + SqliteConnection connection = new SqliteConnection("DataSource=:memory:"); + connection.Open(); + + DbContextOptionsBuilder builder = new DbContextOptionsBuilder() + .UseSqlite(connection); + + EstateManagementContext context = new EstateManagementContext(builder.Options); + context.Database.EnsureCreated(); + + return (context, connection); + } + + [Fact] + public async Task GetEstate_DisposesResolvedScope_WhenReadCompletes() + { + Guid estateId = Guid.NewGuid(); + (EstateManagementContext context, DbConnection connection) = CreateContext(); + + await using (context) + await using (connection) + { + await context.Estates.AddAsync(new Estate + { + EstateId = estateId, + CreatedDateTime = DateTime.UtcNow, + Name = "Test estate", + Reference = "EST-001" + }, CancellationToken.None); + await context.SaveChangesAsync(CancellationToken.None); + + TrackingDisposable trackingDisposable = new TrackingDisposable(); + ServiceProvider serviceProvider = new ServiceCollection() + .AddScoped(_ => trackingDisposable) + .AddTransient(_ => context) + .BuildServiceProvider(); + + IServiceScope scope = serviceProvider.CreateScope(); + _ = scope.ServiceProvider.GetRequiredService(); + + Mock> resolver = new(); + resolver.Setup(r => r.Resolve(It.IsAny(), It.IsAny())) + .Returns(new ResolvedDbContext(scope)); + + TransactionProcessorReadModelRepository repository = new TransactionProcessorReadModelRepository(resolver.Object); + + var result = await repository.GetEstate(estateId, CancellationToken.None); + + result.IsSuccess.ShouldBeTrue(); + trackingDisposable.Disposed.ShouldBeTrue(); + } + } + + private sealed class TrackingDisposable : IDisposable + { + public Boolean Disposed { get; private set; } + + public void Dispose() + { + this.Disposed = true; + } + } + } +} diff --git a/TransactionProcessor.Tests/TransactionProcessor.Tests.csproj b/TransactionProcessor.Tests/TransactionProcessor.Tests.csproj index 5c23316b..83a3ffa7 100644 --- a/TransactionProcessor.Tests/TransactionProcessor.Tests.csproj +++ b/TransactionProcessor.Tests/TransactionProcessor.Tests.csproj @@ -38,6 +38,7 @@ + From 3f73c76bfe63f30e414dc58ccc46a34cc4c94876 Mon Sep 17 00:00:00 2001 From: StuartFerguson Date: Thu, 25 Jun 2026 17:59:49 +0100 Subject: [PATCH 2/4] fixes for package management --- TransactionProcessor/Dockerfile | 6 +++--- TransactionProcessor/Dockerfilewindows | 6 +++--- TransactionProcessor/NuGet.Config | 24 ------------------------ 3 files changed, 6 insertions(+), 30 deletions(-) delete mode 100644 TransactionProcessor/NuGet.Config diff --git a/TransactionProcessor/Dockerfile b/TransactionProcessor/Dockerfile index 68ca4918..e2bec80c 100644 --- a/TransactionProcessor/Dockerfile +++ b/TransactionProcessor/Dockerfile @@ -3,9 +3,9 @@ WORKDIR /app FROM mcr.microsoft.com/dotnet/sdk:10.0 AS build WORKDIR /src -COPY ["TransactionProcessor/NuGet.Config", "."] +COPY ["NuGet.Config", "."] COPY ["TransactionProcessor/TransactionProcessor.csproj", "TransactionProcessor/"] -COPY ["TransactionProcessor/NuGet.Config", "TransactionProcessor/"] +COPY ["NuGet.Config", "TransactionProcessor/"] COPY ["TransactionProcessor.DataTransferObjects/TransactionProcessor.DataTransferObjects.csproj", "TransactionProcessor.DataTransferObjects/"] COPY ["TransactionProcessor.BusinessLogic/TransactionProcessor.BusinessLogic.csproj", "TransactionProcessor.BusinessLogic/"] COPY ["TransactionProcessor.Models/TransactionProcessor.Models.csproj", "TransactionProcessor.Models/"] @@ -27,4 +27,4 @@ RUN dotnet publish "TransactionProcessor.csproj" -c Release -o /app/publish FROM base AS final WORKDIR /app COPY --from=publish /app/publish . -ENTRYPOINT ["dotnet", "TransactionProcessor.dll"] \ No newline at end of file +ENTRYPOINT ["dotnet", "TransactionProcessor.dll"] diff --git a/TransactionProcessor/Dockerfilewindows b/TransactionProcessor/Dockerfilewindows index f834c956..e0758ecd 100644 --- a/TransactionProcessor/Dockerfilewindows +++ b/TransactionProcessor/Dockerfilewindows @@ -4,9 +4,9 @@ WORKDIR /app FROM mcr.microsoft.com/dotnet/sdk:10.0-windowsservercore-ltsc2022 AS build WORKDIR /src -COPY ["TransactionProcessor/NuGet.Config", "."] +COPY ["NuGet.Config", "."] COPY ["TransactionProcessor/TransactionProcessor.csproj", "TransactionProcessor/"] -COPY ["TransactionProcessor/NuGet.Config", "TransactionProcessor/"] +COPY ["NuGet.Config", "TransactionProcessor/"] COPY ["TransactionProcessor.DataTransferObjects/TransactionProcessor.DataTransferObjects.csproj", "TransactionProcessor.DataTransferObjects/"] COPY ["TransactionProcessor.BusinessLogic/TransactionProcessor.BusinessLogic.csproj", "TransactionProcessor.BusinessLogic/"] COPY ["TransactionProcessor.Models/TransactionProcessor.Models.csproj", "TransactionProcessor.Models/"] @@ -27,4 +27,4 @@ RUN dotnet publish "TransactionProcessor.csproj" -c Release -o /app/publish FROM base AS final WORKDIR /app COPY --from=publish /app/publish . -ENTRYPOINT ["dotnet", "TransactionProcessor.dll"] \ No newline at end of file +ENTRYPOINT ["dotnet", "TransactionProcessor.dll"] diff --git a/TransactionProcessor/NuGet.Config b/TransactionProcessor/NuGet.Config deleted file mode 100644 index 3086e202..00000000 --- a/TransactionProcessor/NuGet.Config +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - From c2525af08e1a21496822978a29d6deb808d5b281 Mon Sep 17 00:00:00 2001 From: StuartFerguson Date: Thu, 25 Jun 2026 18:41:49 +0100 Subject: [PATCH 3/4] .. --- NuGet.Config | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/NuGet.Config b/NuGet.Config index 66b50e02..2ecdc238 100644 --- a/NuGet.Config +++ b/NuGet.Config @@ -4,6 +4,20 @@ + + + + + + + + + + + + + + From fce0de7bc263f583e164a312b1d32c9249a66b10 Mon Sep 17 00:00:00 2001 From: StuartFerguson Date: Thu, 25 Jun 2026 19:26:49 +0100 Subject: [PATCH 4/4] :| --- .github/workflows/createrelease.yml | 13 +++++++------ NuGet.Config | 14 -------------- 2 files changed, 7 insertions(+), 20 deletions(-) diff --git a/.github/workflows/createrelease.yml b/.github/workflows/createrelease.yml index 63bfff16..c88e0cba 100644 --- a/.github/workflows/createrelease.yml +++ b/.github/workflows/createrelease.yml @@ -23,7 +23,7 @@ jobs: run: dotnet restore TransactionProcessor.sln --source ${{ secrets.PUBLICFEEDURL }} --source ${{ secrets.PRIVATEFEED_URL }} - name: Build Code - run: dotnet build TransactionProcessor.sln --configuration Release + run: dotnet build TransactionProcessor.sln --configuration Release --no-restore - name: Publish Images to Docker Hub - Pre Release if: ${{ github.event.release.prerelease == true }} @@ -41,11 +41,12 @@ jobs: - name: Publish API if: ${{ github.event.release.prerelease == false }} - run: dotnet publish "TransactionProcessor\TransactionProcessor.csproj" --configuration Release --output publishOutput -r win-x64 --self-contained - -p:Version=${{ steps.get_version.outputs.VERSION }} - -p:AssemblyVersion=${{ steps.get_version.outputs.VERSION }} - -p:FileVersion=${{ steps.get_version.outputs.VERSION }} - -p:InformationalVersion=${{ steps.get_version.outputs.VERSION }} + run: | + dotnet publish "TransactionProcessor/TransactionProcessor.csproj" --configuration Release --output publishOutput -r win-x64 --self-contained --no-build --no-restore \ + -p:Version=${{ steps.get_version.outputs.VERSION }} \ + -p:AssemblyVersion=${{ steps.get_version.outputs.VERSION }} \ + -p:FileVersion=${{ steps.get_version.outputs.VERSION }} \ + -p:InformationalVersion=${{ steps.get_version.outputs.VERSION }} - name: Build Release Package run: | diff --git a/NuGet.Config b/NuGet.Config index 2ecdc238..66b50e02 100644 --- a/NuGet.Config +++ b/NuGet.Config @@ -4,20 +4,6 @@ - - - - - - - - - - - - - -