Cool UnitOfWork convenience method (:

This commit is contained in:
lumijiez
2025-06-21 21:15:10 +03:00
parent ec78744d19
commit d9dfafe07a
4 changed files with 52 additions and 35 deletions

View File

@@ -16,32 +16,22 @@ public class CreateProductCommand : IRequest<ProductDto>
public Guid? CategoryId { get; set; }
}
public class CreateProductHandler(IUnitOfWork unitOfWork, IMapper mapper) : IRequestHandler<CreateProductCommand, ProductDto>
public class CreateProductHandler(IUnitOfWork uw, IMapper mapper) : IRequestHandler<CreateProductCommand, ProductDto>
{
public async Task<ProductDto> Handle(CreateProductCommand request, CancellationToken cancellationToken)
{
await unitOfWork.BeginTransactionAsync(cancellationToken);
try
return await uw.TransactAsync(async () =>
{
var product = mapper.Map<Product>(request);
var createdProduct = await uw.ProductRepository.AddAsync(product, cancellationToken);
var createdProduct = await unitOfWork.ProductRepository.AddAsync(product, cancellationToken);
if (createdProduct.CategoryId.HasValue)
{
createdProduct.Category = (await unitOfWork.CategoryRepository.GetByIdAsync(createdProduct.CategoryId.Value, cancellationToken))!;
createdProduct.Category =
(await uw.CategoryRepository.GetByIdAsync(createdProduct.CategoryId.Value, cancellationToken))!;
}
await unitOfWork.SaveAsync(cancellationToken);
await unitOfWork.CommitTransactionAsync(cancellationToken);
return mapper.Map<ProductDto>(createdProduct);
}
catch
{
await unitOfWork.RollbackTransactionAsync(cancellationToken);
throw;
}
}, cancellationToken);
}
}

View File

@@ -1,35 +1,27 @@
using Imprink.Application.Exceptions;
using MediatR;
namespace Imprink.Application.Commands.Products;
public class DeleteProductCommand : IRequest<bool>
public class DeleteProductCommand : IRequest
{
public Guid Id { get; set; }
}
public class DeleteProductHandler(IUnitOfWork unitOfWork) : IRequestHandler<DeleteProductCommand, bool>
public class DeleteProductHandler(IUnitOfWork uw) : IRequestHandler<DeleteProductCommand>
{
public async Task<bool> Handle(DeleteProductCommand request, CancellationToken cancellationToken)
public async Task Handle(DeleteProductCommand request, CancellationToken cancellationToken)
{
await unitOfWork.BeginTransactionAsync(cancellationToken);
try
await uw.TransactAsync(async () =>
{
var exists = await unitOfWork.ProductRepository.ExistsAsync(request.Id, cancellationToken);
var exists = await uw.ProductRepository.ExistsAsync(request.Id, cancellationToken);
if (!exists)
{
await unitOfWork.RollbackTransactionAsync(cancellationToken);
return false;
throw new NotFoundException($"Product with id {request.Id} not found");
}
await unitOfWork.ProductRepository.DeleteAsync(request.Id, cancellationToken);
await unitOfWork.CommitTransactionAsync(cancellationToken);
return true;
}
catch
{
await unitOfWork.RollbackTransactionAsync(cancellationToken);
throw;
}
await uw.ProductRepository.DeleteAsync(request.Id, cancellationToken);
}, cancellationToken);
}
}

View File

@@ -17,4 +17,6 @@ public interface IUnitOfWork
Task BeginTransactionAsync(CancellationToken cancellationToken = default);
Task CommitTransactionAsync(CancellationToken cancellationToken = default);
Task RollbackTransactionAsync(CancellationToken cancellationToken = default);
Task<T> TransactAsync<T>(Func<Task<T>> operation, CancellationToken cancellationToken = default);
Task TransactAsync(Func<Task> operation, CancellationToken cancellationToken = default);
}

View File

@@ -43,4 +43,37 @@ public class UnitOfWork(
{
await context.Database.RollbackTransactionAsync(cancellationToken);
}
public async Task<T> TransactAsync<T>(Func<Task<T>> operation, CancellationToken cancellationToken = default)
{
await BeginTransactionAsync(cancellationToken);
try
{
var result = await operation();
await SaveAsync(cancellationToken);
await CommitTransactionAsync(cancellationToken);
return result;
}
catch
{
await RollbackTransactionAsync(cancellationToken);
throw;
}
}
public async Task TransactAsync(Func<Task> operation, CancellationToken cancellationToken = default)
{
await BeginTransactionAsync(cancellationToken);
try
{
await operation();
await SaveAsync(cancellationToken);
await CommitTransactionAsync(cancellationToken);
}
catch
{
await RollbackTransactionAsync(cancellationToken);
throw;
}
}
}