Loading BusinessLayer.Tests/Services/ProductServiceTests.cs +3 −1 Original line number Original line Diff line number Diff line Loading @@ -7,6 +7,7 @@ using Commons.Enums; using JuiceWorld.Entities; using JuiceWorld.Entities; using JuiceWorld.QueryObjects; using JuiceWorld.QueryObjects; using JuiceWorld.Repositories; using JuiceWorld.Repositories; using JuiceWorld.UnitOfWork; using Microsoft.Extensions.Caching.Memory; using Microsoft.Extensions.Caching.Memory; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging; using TestUtilities.MockedObjects; using TestUtilities.MockedObjects; Loading @@ -28,7 +29,8 @@ public class ProductServiceTests var mapper = config.CreateMapper(); var mapper = config.CreateMapper(); var loggerFactory = LoggerFactory.Create(builder => builder.AddConsole()); var loggerFactory = LoggerFactory.Create(builder => builder.AddConsole()); var cache = new MemoryCache(new MemoryCacheOptions()); var cache = new MemoryCache(new MemoryCacheOptions()); _productService = new ProductService(productRepository, mapper, cache, new QueryObject<Product>(dbContext)); var unitOfwork = new ProductUnitOfWork(dbContext); _productService = new ProductService(productRepository, mapper, cache, new QueryObject<Product>(dbContext), unitOfwork); } } [Fact] [Fact] Loading BusinessLayer.Tests/Stubs/ProductServiceStubTests.cs +6 −31 Original line number Original line Diff line number Diff line Loading @@ -7,6 +7,7 @@ using Commons.Enums; using Infrastructure.QueryObjects; using Infrastructure.QueryObjects; using Infrastructure.Repositories; using Infrastructure.Repositories; using JuiceWorld.Entities; using JuiceWorld.Entities; using JuiceWorld.UnitOfWork; using Microsoft.Extensions.Caching.Memory; using Microsoft.Extensions.Caching.Memory; using Moq; using Moq; using Xunit; using Xunit; Loading @@ -18,7 +19,9 @@ namespace BusinessLayer.Tests.Stubs { { private readonly IProductService _productService; private readonly IProductService _productService; private readonly Mock<IRepository<Product>> _productRepositoryMock; private readonly Mock<IRepository<Product>> _productRepositoryMock; private readonly Mock<IRepository<Tag>> _tagRepositoryMock; private readonly IMapper _mapper; private readonly IMapper _mapper; private readonly Mock<ProductUnitOfWork> _unitofWork; private readonly List<Product> _products = new List<Product> private readonly List<Product> _products = new List<Product> { { Loading Loading @@ -53,7 +56,9 @@ namespace BusinessLayer.Tests.Stubs _mapper = config.CreateMapper(); _mapper = config.CreateMapper(); var cache = new MemoryCache(new MemoryCacheOptions()); var cache = new MemoryCache(new MemoryCacheOptions()); // Initialize the service // Initialize the service _productService = new ProductService(_productRepositoryMock.Object, _mapper, cache, queryObjectMock.Object); _tagRepositoryMock = new Mock<IRepository<Tag>>(); _unitofWork = new Mock<ProductUnitOfWork>(_productRepositoryMock.Object, _tagRepositoryMock.Object); _productService = new ProductService(_productRepositoryMock.Object, _mapper, cache, queryObjectMock.Object, _unitofWork.Object); } } [Fact] [Fact] Loading Loading @@ -116,36 +121,6 @@ namespace BusinessLayer.Tests.Stubs Assert.Equal(productDto.ManufacturerId, result.ManufacturerId); Assert.Equal(productDto.ManufacturerId, result.ManufacturerId); } } [Fact] public async Task UpdateProductAsync_Simple() { // Arrange var productDto = new ProductDto { Id = 1, Name = "Updated Product", Price = 120m, Description = "Updated Description", Category = ProductCategory.Testosterone, ManufacturerId = 1 }; var updatedProduct = _mapper.Map<Product>(productDto); _productRepositoryMock.Setup(repo => repo.GetByIdAsync(productDto.Id)).ReturnsAsync(_products[0]); _productRepositoryMock.Setup(repo => repo.UpdateAsync(It.IsAny<Product>(), null)).ReturnsAsync(updatedProduct); // Act var result = await _productService.UpdateProductAsync(productDto); // Assert Assert.NotNull(result); Assert.Equal(productDto.Name, result.Name); Assert.Equal(productDto.Price, result.Price); Assert.Equal(productDto.Description, result.Description); Assert.Equal(productDto.Category, result.Category); Assert.Equal(productDto.ManufacturerId, result.ManufacturerId); } [Fact] [Fact] public async Task DeleteProductByIdAsync_Simple() public async Task DeleteProductByIdAsync_Simple() { { Loading BusinessLayer/Services/ManufacturerService.cs +6 −13 Original line number Original line Diff line number Diff line Loading @@ -38,9 +38,6 @@ public class ManufacturerService( public async Task<FilteredResult<ManufacturerDto>> GetManufacturersAsync( public async Task<FilteredResult<ManufacturerDto>> GetManufacturersAsync( ManufacturerFilterDto manufacturerFilterDto) ManufacturerFilterDto manufacturerFilterDto) { string cacheKey = $"{_cacheKeyPrefix}-manufacturers{JsonSerializer.Serialize(manufacturerFilterDto)}"; if (!memoryCache.TryGetValue(cacheKey, out FilteredResult<Manufacturer>? value)) { { var query = manufacturerQueryObject var query = manufacturerQueryObject .Filter(m => manufacturerFilterDto.Name == null || .Filter(m => manufacturerFilterDto.Name == null || Loading @@ -48,12 +45,8 @@ public class ManufacturerService( .Paginate(manufacturerFilterDto.PageIndex, manufacturerFilterDto.PageSize) .Paginate(manufacturerFilterDto.PageIndex, manufacturerFilterDto.PageSize) .OrderBy(m => m.Id); .OrderBy(m => m.Id); value = await query.ExecuteAsync(); var value = await query.ExecuteAsync(); var cacheEntryOptions = new MemoryCacheEntryOptions() .SetAbsoluteExpiration(TimeSpan.FromSeconds(30)); memoryCache.Set(cacheKey, value, cacheEntryOptions); } return new FilteredResult<ManufacturerDto> return new FilteredResult<ManufacturerDto> { { Loading BusinessLayer/Services/OrderService.cs +31 −21 Original line number Original line Diff line number Diff line Loading @@ -104,10 +104,6 @@ public class OrderService( public async Task<FilteredResult<OrderDto>> GetOrdersByUserIdAsync(int userId, PaginationDto paginationDto) public async Task<FilteredResult<OrderDto>> GetOrdersByUserIdAsync(int userId, PaginationDto paginationDto) { { string cacheKey = $"{_cacheKeyPrefix}-Orders{userId}{JsonSerializer.Serialize(paginationDto)}"; if (!memoryCache.TryGetValue(cacheKey, out FilteredResult<Order>? value)) { var query = orderQueryObject.Filter(o => o.UserId == userId) var query = orderQueryObject.Filter(o => o.UserId == userId) .OrderBy( .OrderBy( new (Expression<Func<Order, object>> KeySelector, bool IsDesc)[] new (Expression<Func<Order, object>> KeySelector, bool IsDesc)[] Loading @@ -117,12 +113,7 @@ public class OrderService( }) }) .Paginate(paginationDto.PageIndex, paginationDto.PageSize); .Paginate(paginationDto.PageIndex, paginationDto.PageSize); value = await query.ExecuteAsync(); var value = await query.ExecuteAsync(); var cacheEntryOptions = new MemoryCacheEntryOptions() .SetAbsoluteExpiration(TimeSpan.FromSeconds(30)); memoryCache.Set(cacheKey, value, cacheEntryOptions); } return new FilteredResult<OrderDto> return new FilteredResult<OrderDto> { { Loading @@ -140,19 +131,36 @@ public class OrderService( public async Task<OrderDetailDto?> GetOrderDetailByIdAsync(int id) public async Task<OrderDetailDto?> GetOrderDetailByIdAsync(int id) { { var order = await orderRepository.GetByIdAsync(id, string cacheKey = $"{_cacheKeyPrefix}-OrderDetail{id}"; nameof(Order.OrderProducts), $"{nameof(Order.OrderProducts)}.{nameof(OrderProduct.Product)}", nameof(User)); if (!memoryCache.TryGetValue(cacheKey, out Order? value)) return order is null ? null : mapper.Map<OrderDetailDto>(order); { value = await orderRepository.GetByIdAsync(id, nameof(Order.OrderProducts), $"{nameof(Order.OrderProducts)}.{nameof(OrderProduct.Product)}", nameof(User)); var cacheEntryOptions = new MemoryCacheEntryOptions() .SetAbsoluteExpiration(TimeSpan.FromSeconds(30)); memoryCache.Set(cacheKey, value, cacheEntryOptions); } return value is null ? null : mapper.Map<OrderDetailDto>(value); } } public async Task<OrderDto?> UpdateOrderAsync(OrderDto orderDto) public async Task<OrderDto?> UpdateOrderAsync(OrderDto orderDto) { { string cacheKey = $"{_cacheKeyPrefix}-OrderDetail{orderDto.Id}"; memoryCache.Remove(cacheKey); var updatedOrder = await orderRepository.UpdateAsync(mapper.Map<Order>(orderDto)); var updatedOrder = await orderRepository.UpdateAsync(mapper.Map<Order>(orderDto)); return updatedOrder is null ? null : mapper.Map<OrderDto>(updatedOrder); return updatedOrder is null ? null : mapper.Map<OrderDto>(updatedOrder); } } public async Task<OrderDto?> UpdateOrderAsync(OrderDetailDto orderDto) public async Task<OrderDto?> UpdateOrderAsync(OrderDetailDto orderDto) { { string cacheKey = $"{_cacheKeyPrefix}-OrderDetail{orderDto.Id}"; memoryCache.Remove(cacheKey); var order = mapper.Map<Order>(orderDto); var order = mapper.Map<Order>(orderDto); order.OrderProducts = []; order.OrderProducts = []; var updatedOrder = await orderUnitOfWork.OrderRepository.UpdateAsync(order); var updatedOrder = await orderUnitOfWork.OrderRepository.UpdateAsync(order); Loading Loading @@ -199,6 +207,8 @@ public class OrderService( public Task<bool> DeleteOrderByIdAsync(int id) public Task<bool> DeleteOrderByIdAsync(int id) { { string cacheKey = $"{_cacheKeyPrefix}-OrderDetail{id}"; memoryCache.Remove(cacheKey); return orderRepository.DeleteAsync(id); return orderRepository.DeleteAsync(id); } } } } BusinessLayer/Services/ProductService.cs +21 −5 Original line number Original line Diff line number Diff line Loading @@ -6,6 +6,7 @@ using Commons.Enums; using Infrastructure.QueryObjects; using Infrastructure.QueryObjects; using Infrastructure.Repositories; using Infrastructure.Repositories; using JuiceWorld.Entities; using JuiceWorld.Entities; using JuiceWorld.UnitOfWork; using Microsoft.Extensions.Caching.Memory; using Microsoft.Extensions.Caching.Memory; namespace BusinessLayer.Services; namespace BusinessLayer.Services; Loading @@ -14,7 +15,9 @@ public class ProductService( IRepository<Product> productRepository, IRepository<Product> productRepository, IMapper mapper, IMapper mapper, IMemoryCache memoryCache, IMemoryCache memoryCache, IQueryObject<Product> queryObject) : IProductService IQueryObject<Product> queryObject, ProductUnitOfWork productUnitOfWork ) : IProductService { { private string _cacheKeyPrefix = nameof(ProductService); private string _cacheKeyPrefix = nameof(ProductService); public async Task<ProductDto?> CreateProductAsync(ProductDto productDto) public async Task<ProductDto?> CreateProductAsync(ProductDto productDto) Loading Loading @@ -127,20 +130,33 @@ public class ProductService( public async Task<ProductDto?> UpdateProductAsync(ProductDto productDto) public async Task<ProductDto?> UpdateProductAsync(ProductDto productDto) { { var oldProduct = await productRepository.GetByIdAsync(productDto.Id); string cacheKeyDetail = $"{_cacheKeyPrefix}-productDetail{productDto.Id}"; memoryCache.Remove(cacheKeyDetail); string cacheKey1 = $"{_cacheKeyPrefix}-product{productDto.Id}"; memoryCache.Remove(cacheKey1); var oldProduct = await productUnitOfWork.ProductRepository.GetByIdAsync(productDto.Id); if (oldProduct is null) if (oldProduct is null) { { return null; return null; } } var updatedProduct = await productRepository.UpdateAsync(mapper.Map<Product>(productDto)); var product = mapper.Map<Product>(productDto); oldProduct.Tags.Clear(); var tags = await productUnitOfWork.TagRepository.GetByIdRangeAsync(productDto.TagIds.Cast<object>()); product.Tags = tags.ToList(); var updatedProduct = await productUnitOfWork.ProductRepository.UpdateAsync(product); await productUnitOfWork.Commit(); return updatedProduct is null ? null : mapper.Map<ProductDto>(updatedProduct); return updatedProduct is null ? null : mapper.Map<ProductDto>(updatedProduct); } } public async Task<bool> DeleteProductByIdAsync(int id) public async Task<bool> DeleteProductByIdAsync(int id) { { string cacheKey = $"{_cacheKeyPrefix}-productDetail{id}"; string cacheKeyDetail = $"{_cacheKeyPrefix}-productDetail{id}"; memoryCache.Remove(cacheKey); memoryCache.Remove(cacheKeyDetail); string cacheKey1 = $"{_cacheKeyPrefix}-product{id}"; memoryCache.Remove(cacheKey1); return await productRepository.DeleteAsync(id); return await productRepository.DeleteAsync(id); } } } } Loading
BusinessLayer.Tests/Services/ProductServiceTests.cs +3 −1 Original line number Original line Diff line number Diff line Loading @@ -7,6 +7,7 @@ using Commons.Enums; using JuiceWorld.Entities; using JuiceWorld.Entities; using JuiceWorld.QueryObjects; using JuiceWorld.QueryObjects; using JuiceWorld.Repositories; using JuiceWorld.Repositories; using JuiceWorld.UnitOfWork; using Microsoft.Extensions.Caching.Memory; using Microsoft.Extensions.Caching.Memory; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging; using TestUtilities.MockedObjects; using TestUtilities.MockedObjects; Loading @@ -28,7 +29,8 @@ public class ProductServiceTests var mapper = config.CreateMapper(); var mapper = config.CreateMapper(); var loggerFactory = LoggerFactory.Create(builder => builder.AddConsole()); var loggerFactory = LoggerFactory.Create(builder => builder.AddConsole()); var cache = new MemoryCache(new MemoryCacheOptions()); var cache = new MemoryCache(new MemoryCacheOptions()); _productService = new ProductService(productRepository, mapper, cache, new QueryObject<Product>(dbContext)); var unitOfwork = new ProductUnitOfWork(dbContext); _productService = new ProductService(productRepository, mapper, cache, new QueryObject<Product>(dbContext), unitOfwork); } } [Fact] [Fact] Loading
BusinessLayer.Tests/Stubs/ProductServiceStubTests.cs +6 −31 Original line number Original line Diff line number Diff line Loading @@ -7,6 +7,7 @@ using Commons.Enums; using Infrastructure.QueryObjects; using Infrastructure.QueryObjects; using Infrastructure.Repositories; using Infrastructure.Repositories; using JuiceWorld.Entities; using JuiceWorld.Entities; using JuiceWorld.UnitOfWork; using Microsoft.Extensions.Caching.Memory; using Microsoft.Extensions.Caching.Memory; using Moq; using Moq; using Xunit; using Xunit; Loading @@ -18,7 +19,9 @@ namespace BusinessLayer.Tests.Stubs { { private readonly IProductService _productService; private readonly IProductService _productService; private readonly Mock<IRepository<Product>> _productRepositoryMock; private readonly Mock<IRepository<Product>> _productRepositoryMock; private readonly Mock<IRepository<Tag>> _tagRepositoryMock; private readonly IMapper _mapper; private readonly IMapper _mapper; private readonly Mock<ProductUnitOfWork> _unitofWork; private readonly List<Product> _products = new List<Product> private readonly List<Product> _products = new List<Product> { { Loading Loading @@ -53,7 +56,9 @@ namespace BusinessLayer.Tests.Stubs _mapper = config.CreateMapper(); _mapper = config.CreateMapper(); var cache = new MemoryCache(new MemoryCacheOptions()); var cache = new MemoryCache(new MemoryCacheOptions()); // Initialize the service // Initialize the service _productService = new ProductService(_productRepositoryMock.Object, _mapper, cache, queryObjectMock.Object); _tagRepositoryMock = new Mock<IRepository<Tag>>(); _unitofWork = new Mock<ProductUnitOfWork>(_productRepositoryMock.Object, _tagRepositoryMock.Object); _productService = new ProductService(_productRepositoryMock.Object, _mapper, cache, queryObjectMock.Object, _unitofWork.Object); } } [Fact] [Fact] Loading Loading @@ -116,36 +121,6 @@ namespace BusinessLayer.Tests.Stubs Assert.Equal(productDto.ManufacturerId, result.ManufacturerId); Assert.Equal(productDto.ManufacturerId, result.ManufacturerId); } } [Fact] public async Task UpdateProductAsync_Simple() { // Arrange var productDto = new ProductDto { Id = 1, Name = "Updated Product", Price = 120m, Description = "Updated Description", Category = ProductCategory.Testosterone, ManufacturerId = 1 }; var updatedProduct = _mapper.Map<Product>(productDto); _productRepositoryMock.Setup(repo => repo.GetByIdAsync(productDto.Id)).ReturnsAsync(_products[0]); _productRepositoryMock.Setup(repo => repo.UpdateAsync(It.IsAny<Product>(), null)).ReturnsAsync(updatedProduct); // Act var result = await _productService.UpdateProductAsync(productDto); // Assert Assert.NotNull(result); Assert.Equal(productDto.Name, result.Name); Assert.Equal(productDto.Price, result.Price); Assert.Equal(productDto.Description, result.Description); Assert.Equal(productDto.Category, result.Category); Assert.Equal(productDto.ManufacturerId, result.ManufacturerId); } [Fact] [Fact] public async Task DeleteProductByIdAsync_Simple() public async Task DeleteProductByIdAsync_Simple() { { Loading
BusinessLayer/Services/ManufacturerService.cs +6 −13 Original line number Original line Diff line number Diff line Loading @@ -38,9 +38,6 @@ public class ManufacturerService( public async Task<FilteredResult<ManufacturerDto>> GetManufacturersAsync( public async Task<FilteredResult<ManufacturerDto>> GetManufacturersAsync( ManufacturerFilterDto manufacturerFilterDto) ManufacturerFilterDto manufacturerFilterDto) { string cacheKey = $"{_cacheKeyPrefix}-manufacturers{JsonSerializer.Serialize(manufacturerFilterDto)}"; if (!memoryCache.TryGetValue(cacheKey, out FilteredResult<Manufacturer>? value)) { { var query = manufacturerQueryObject var query = manufacturerQueryObject .Filter(m => manufacturerFilterDto.Name == null || .Filter(m => manufacturerFilterDto.Name == null || Loading @@ -48,12 +45,8 @@ public class ManufacturerService( .Paginate(manufacturerFilterDto.PageIndex, manufacturerFilterDto.PageSize) .Paginate(manufacturerFilterDto.PageIndex, manufacturerFilterDto.PageSize) .OrderBy(m => m.Id); .OrderBy(m => m.Id); value = await query.ExecuteAsync(); var value = await query.ExecuteAsync(); var cacheEntryOptions = new MemoryCacheEntryOptions() .SetAbsoluteExpiration(TimeSpan.FromSeconds(30)); memoryCache.Set(cacheKey, value, cacheEntryOptions); } return new FilteredResult<ManufacturerDto> return new FilteredResult<ManufacturerDto> { { Loading
BusinessLayer/Services/OrderService.cs +31 −21 Original line number Original line Diff line number Diff line Loading @@ -104,10 +104,6 @@ public class OrderService( public async Task<FilteredResult<OrderDto>> GetOrdersByUserIdAsync(int userId, PaginationDto paginationDto) public async Task<FilteredResult<OrderDto>> GetOrdersByUserIdAsync(int userId, PaginationDto paginationDto) { { string cacheKey = $"{_cacheKeyPrefix}-Orders{userId}{JsonSerializer.Serialize(paginationDto)}"; if (!memoryCache.TryGetValue(cacheKey, out FilteredResult<Order>? value)) { var query = orderQueryObject.Filter(o => o.UserId == userId) var query = orderQueryObject.Filter(o => o.UserId == userId) .OrderBy( .OrderBy( new (Expression<Func<Order, object>> KeySelector, bool IsDesc)[] new (Expression<Func<Order, object>> KeySelector, bool IsDesc)[] Loading @@ -117,12 +113,7 @@ public class OrderService( }) }) .Paginate(paginationDto.PageIndex, paginationDto.PageSize); .Paginate(paginationDto.PageIndex, paginationDto.PageSize); value = await query.ExecuteAsync(); var value = await query.ExecuteAsync(); var cacheEntryOptions = new MemoryCacheEntryOptions() .SetAbsoluteExpiration(TimeSpan.FromSeconds(30)); memoryCache.Set(cacheKey, value, cacheEntryOptions); } return new FilteredResult<OrderDto> return new FilteredResult<OrderDto> { { Loading @@ -140,19 +131,36 @@ public class OrderService( public async Task<OrderDetailDto?> GetOrderDetailByIdAsync(int id) public async Task<OrderDetailDto?> GetOrderDetailByIdAsync(int id) { { var order = await orderRepository.GetByIdAsync(id, string cacheKey = $"{_cacheKeyPrefix}-OrderDetail{id}"; nameof(Order.OrderProducts), $"{nameof(Order.OrderProducts)}.{nameof(OrderProduct.Product)}", nameof(User)); if (!memoryCache.TryGetValue(cacheKey, out Order? value)) return order is null ? null : mapper.Map<OrderDetailDto>(order); { value = await orderRepository.GetByIdAsync(id, nameof(Order.OrderProducts), $"{nameof(Order.OrderProducts)}.{nameof(OrderProduct.Product)}", nameof(User)); var cacheEntryOptions = new MemoryCacheEntryOptions() .SetAbsoluteExpiration(TimeSpan.FromSeconds(30)); memoryCache.Set(cacheKey, value, cacheEntryOptions); } return value is null ? null : mapper.Map<OrderDetailDto>(value); } } public async Task<OrderDto?> UpdateOrderAsync(OrderDto orderDto) public async Task<OrderDto?> UpdateOrderAsync(OrderDto orderDto) { { string cacheKey = $"{_cacheKeyPrefix}-OrderDetail{orderDto.Id}"; memoryCache.Remove(cacheKey); var updatedOrder = await orderRepository.UpdateAsync(mapper.Map<Order>(orderDto)); var updatedOrder = await orderRepository.UpdateAsync(mapper.Map<Order>(orderDto)); return updatedOrder is null ? null : mapper.Map<OrderDto>(updatedOrder); return updatedOrder is null ? null : mapper.Map<OrderDto>(updatedOrder); } } public async Task<OrderDto?> UpdateOrderAsync(OrderDetailDto orderDto) public async Task<OrderDto?> UpdateOrderAsync(OrderDetailDto orderDto) { { string cacheKey = $"{_cacheKeyPrefix}-OrderDetail{orderDto.Id}"; memoryCache.Remove(cacheKey); var order = mapper.Map<Order>(orderDto); var order = mapper.Map<Order>(orderDto); order.OrderProducts = []; order.OrderProducts = []; var updatedOrder = await orderUnitOfWork.OrderRepository.UpdateAsync(order); var updatedOrder = await orderUnitOfWork.OrderRepository.UpdateAsync(order); Loading Loading @@ -199,6 +207,8 @@ public class OrderService( public Task<bool> DeleteOrderByIdAsync(int id) public Task<bool> DeleteOrderByIdAsync(int id) { { string cacheKey = $"{_cacheKeyPrefix}-OrderDetail{id}"; memoryCache.Remove(cacheKey); return orderRepository.DeleteAsync(id); return orderRepository.DeleteAsync(id); } } } }
BusinessLayer/Services/ProductService.cs +21 −5 Original line number Original line Diff line number Diff line Loading @@ -6,6 +6,7 @@ using Commons.Enums; using Infrastructure.QueryObjects; using Infrastructure.QueryObjects; using Infrastructure.Repositories; using Infrastructure.Repositories; using JuiceWorld.Entities; using JuiceWorld.Entities; using JuiceWorld.UnitOfWork; using Microsoft.Extensions.Caching.Memory; using Microsoft.Extensions.Caching.Memory; namespace BusinessLayer.Services; namespace BusinessLayer.Services; Loading @@ -14,7 +15,9 @@ public class ProductService( IRepository<Product> productRepository, IRepository<Product> productRepository, IMapper mapper, IMapper mapper, IMemoryCache memoryCache, IMemoryCache memoryCache, IQueryObject<Product> queryObject) : IProductService IQueryObject<Product> queryObject, ProductUnitOfWork productUnitOfWork ) : IProductService { { private string _cacheKeyPrefix = nameof(ProductService); private string _cacheKeyPrefix = nameof(ProductService); public async Task<ProductDto?> CreateProductAsync(ProductDto productDto) public async Task<ProductDto?> CreateProductAsync(ProductDto productDto) Loading Loading @@ -127,20 +130,33 @@ public class ProductService( public async Task<ProductDto?> UpdateProductAsync(ProductDto productDto) public async Task<ProductDto?> UpdateProductAsync(ProductDto productDto) { { var oldProduct = await productRepository.GetByIdAsync(productDto.Id); string cacheKeyDetail = $"{_cacheKeyPrefix}-productDetail{productDto.Id}"; memoryCache.Remove(cacheKeyDetail); string cacheKey1 = $"{_cacheKeyPrefix}-product{productDto.Id}"; memoryCache.Remove(cacheKey1); var oldProduct = await productUnitOfWork.ProductRepository.GetByIdAsync(productDto.Id); if (oldProduct is null) if (oldProduct is null) { { return null; return null; } } var updatedProduct = await productRepository.UpdateAsync(mapper.Map<Product>(productDto)); var product = mapper.Map<Product>(productDto); oldProduct.Tags.Clear(); var tags = await productUnitOfWork.TagRepository.GetByIdRangeAsync(productDto.TagIds.Cast<object>()); product.Tags = tags.ToList(); var updatedProduct = await productUnitOfWork.ProductRepository.UpdateAsync(product); await productUnitOfWork.Commit(); return updatedProduct is null ? null : mapper.Map<ProductDto>(updatedProduct); return updatedProduct is null ? null : mapper.Map<ProductDto>(updatedProduct); } } public async Task<bool> DeleteProductByIdAsync(int id) public async Task<bool> DeleteProductByIdAsync(int id) { { string cacheKey = $"{_cacheKeyPrefix}-productDetail{id}"; string cacheKeyDetail = $"{_cacheKeyPrefix}-productDetail{id}"; memoryCache.Remove(cacheKey); memoryCache.Remove(cacheKeyDetail); string cacheKey1 = $"{_cacheKeyPrefix}-product{id}"; memoryCache.Remove(cacheKey1); return await productRepository.DeleteAsync(id); return await productRepository.DeleteAsync(id); } } } }