diff --git a/Mango.Nop.Core/Interfaces/IMgDbContextBase.cs b/Mango.Nop.Core/Interfaces/IMgDbContextBase.cs index 8985c31..6e3ac79 100644 --- a/Mango.Nop.Core/Interfaces/IMgDbContextBase.cs +++ b/Mango.Nop.Core/Interfaces/IMgDbContextBase.cs @@ -1,6 +1,17 @@ -namespace Mango.Nop.Core.Interfaces; +using Mango.Nop.Core.Loggers; +using Nop.Data; +using System.Transactions; + +namespace Mango.Nop.Core.Interfaces; public interface IMgDbContextBase //: IAcDbContextBase { + ILogger Logger { get; init; } + INopDataProvider DataProvider { get; init; } + bool Transaction(Func callbackTransactionBody, bool throwException = false); + bool TransactionSafe(Func callbackTransactionBody, bool throwException = false); + + Task TransactionAsync(Func> callbackTransactionBody, bool throwException = false); + Task TransactionSafeAsync(Func> callbackTransactionBody, bool throwException = false); } \ No newline at end of file diff --git a/Mango.Nop.Core/Mango.Nop.Core.csproj b/Mango.Nop.Core/Mango.Nop.Core.csproj index 0ca51c8..2919bda 100644 --- a/Mango.Nop.Core/Mango.Nop.Core.csproj +++ b/Mango.Nop.Core/Mango.Nop.Core.csproj @@ -37,6 +37,9 @@ ..\..\..\..\..\..\Aycode\Source\AyCode.Core\AyCode.Services.Server\bin\FruitBank\Debug\net9.0\AyCode.Interfaces.Server.dll + + ..\..\..\..\..\..\Aycode\Source\AyCode.Core\AyCode.Services.Server\bin\FruitBank\Debug\net9.0\AyCode.Utils.dll + diff --git a/Mango.Nop.Core/Models/MgLoginModelResponse.cs b/Mango.Nop.Core/Models/MgLoginModelResponse.cs index 2511b1c..4d60518 100644 --- a/Mango.Nop.Core/Models/MgLoginModelResponse.cs +++ b/Mango.Nop.Core/Models/MgLoginModelResponse.cs @@ -1,4 +1,5 @@ using AyCode.Interfaces; +using AyCode.Utils.Extensions; using Mango.Nop.Core.Dtos; using Nop.Core.Domain.Customers; @@ -6,7 +7,7 @@ namespace Mango.Nop.Core.Models; public class MgLoginModelResponse : IAcModelDtoBaseEmpty { - public CustomerDto CustomerDto { get; set; } + public CustomerDto? CustomerDto { get; set; } public string ErrorMessage { get; set; } public MgLoginModelResponse() @@ -18,4 +19,6 @@ public class MgLoginModelResponse : IAcModelDtoBaseEmpty CustomerDto = customerDto; ErrorMessage = errorMessage; } + + public bool IsSuccesLogin => CustomerDto != null && ErrorMessage.IsNullOrWhiteSpace(); } \ No newline at end of file diff --git a/Mango.Nop.Core/Repositories/MgDbContextBase.cs b/Mango.Nop.Core/Repositories/MgDbContextBase.cs index 9493ae3..8b9678f 100644 --- a/Mango.Nop.Core/Repositories/MgDbContextBase.cs +++ b/Mango.Nop.Core/Repositories/MgDbContextBase.cs @@ -1,12 +1,13 @@ -using AyCode.Core.Loggers; +using System.Transactions; +using AyCode.Core.Consts; +using AyCode.Core.Helpers; +using AyCode.Core.Loggers; +using AyCode.Utils.Extensions; using Mango.Nop.Core.Interfaces; using Mango.Nop.Core.Loggers; -using Microsoft.AspNetCore.Http; +using Mango.Nop.Services; using Nop.Core.Caching; -using Nop.Core.Domain.Catalog; -using Nop.Core.Events; using Nop.Data; -using Nop.Services.Events; namespace Mango.Nop.Core.Repositories; @@ -17,14 +18,111 @@ public class MgDbContextBase : IMgDbContextBase private readonly CacheKey _auctionAllKey = new("Nop.auction.all-{0}", AUCTION_PATTERN_KEY); public const string AUCTION_PATTERN_KEY = "Nop.auction."; + protected readonly IMgLockService LockService; - protected ILogger Logger; - protected INopDataProvider DataProvider; - //protected IHttpContextAccessor HttpContextAccessor; + public ILogger Logger { get; init; } + public INopDataProvider DataProvider { get; init; } - public MgDbContextBase(INopDataProvider dataProvider, IEnumerable logWriters) + //public IHttpContextAccessor HttpContextAccessor { get; init; } + + public MgDbContextBase(INopDataProvider dataProvider, IMgLockService lockService, IEnumerable logWriters) { + LockService = lockService; + Logger = new Logger(logWriters.ToArray()); DataProvider = dataProvider; } + + public bool Transaction(Func callbackTransactionBody, bool throwException = false) + => TransactionInner(callbackTransactionBody, throwException); + + /// + /// Using LoskService, global lock! + /// + /// + /// + /// + public bool TransactionSafe(Func callbackTransactionBody, bool throwException = false) + { + using (LockService.SemaphoreSlim.UseWait()) + { + return TransactionInner(callbackTransactionBody, throwException); + } + } + + public Task TransactionAsync(Func> callbackTransactionBody, bool throwException = false) + => TaskHelper.ToThreadPoolTask(() => TransactionInnerAsync(callbackTransactionBody, throwException)); + + /// + /// Using LoskService, global lock! + /// + /// + /// + /// + public Task TransactionSafeAsync(Func> callbackTransactionBody, bool throwException = false) + { + return TaskHelper.ToThreadPoolTask(async () => + { + using (await LockService.SemaphoreSlim.UseWaitAsync()) + { + return await TransactionInnerAsync(callbackTransactionBody, throwException); + } + }); + } + + private async Task TransactionInnerAsync(Func> callbackTransactionBody, bool throwException = false) + { + bool result; + + try + { + using (var transaction = new TransactionScope( /*TransactionScopeOption.RequiresNew, */TransactionScopeAsyncFlowOption.Enabled)) + { + result = await callbackTransactionBody(transaction); + + if (result) transaction.Complete(); + } + + if (!result) Logger.Warning($"TransactionInnerAsync({this}) transaction ROLLBACK!"); + } + catch (Exception ex) + { + if (throwException) throw; + + result = false; + Logger.Error($"TransactionInnerAsync({this}) transaction error! ex: {ex.Message}{AcEnv.NL}", ex); + } + + return result; + } + + private bool TransactionInner(Func callbackTransactionBody, bool throwException = false) + { + bool result; + + try + { + using var transaction = new TransactionScope( /*TransactionScopeOption.RequiresNew, */TransactionScopeAsyncFlowOption.Enabled); + + result = callbackTransactionBody(transaction); + + if (result) transaction.Complete(); + else Logger.Warning($"TransactionInner({this}) transaction ROLLBACK!"); + } + catch (Exception ex) + { + if (throwException) throw; + + result = false; + Logger.Error($"TransactionInnerAsync({this}) transaction error! ex: {ex.Message}{AcEnv.NL}", ex); + } + + return result; + } + + + public override string ToString() + { + return GetType().Name; + } } \ No newline at end of file diff --git a/Mango.Nop.Services/IMgLockService.cs b/Mango.Nop.Core/Services/IMgLockService.cs similarity index 100% rename from Mango.Nop.Services/IMgLockService.cs rename to Mango.Nop.Core/Services/IMgLockService.cs