订单创建命令处理程序
This commit is contained in:
parent
923089b83b
commit
348ea248a6
@ -0,0 +1,53 @@
|
|||||||
|
using HelloShop.OrderingService.Extensions;
|
||||||
|
using HelloShop.OrderingService.Infrastructure;
|
||||||
|
using MediatR;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using System.Data;
|
||||||
|
|
||||||
|
namespace HelloShop.OrderingService.Behaviors
|
||||||
|
{
|
||||||
|
public class TransactionBehavior<TRequest, TResponse>(OrderingServiceDbContext dbContext, ILoggerFactory loggerFactory) : IPipelineBehavior<TRequest, TResponse> where TRequest : IRequest<TResponse>
|
||||||
|
{
|
||||||
|
private readonly ILogger<TransactionBehavior<TRequest, TResponse>> _logger = loggerFactory.CreateLogger<TransactionBehavior<TRequest, TResponse>>();
|
||||||
|
|
||||||
|
public async Task<TResponse> Handle(TRequest request, RequestHandlerDelegate<TResponse> next, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
TResponse? response = default;
|
||||||
|
|
||||||
|
string typeName = request.GetGenericTypeName();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (dbContext.Database.CurrentTransaction != null)
|
||||||
|
{
|
||||||
|
return await next();
|
||||||
|
}
|
||||||
|
|
||||||
|
var strategy = dbContext.Database.CreateExecutionStrategy();
|
||||||
|
|
||||||
|
await strategy.ExecuteAsync(async () =>
|
||||||
|
{
|
||||||
|
using var transaction = await dbContext.Database.BeginTransactionAsync(IsolationLevel.ReadCommitted);
|
||||||
|
|
||||||
|
using (_logger.BeginScope(new List<KeyValuePair<string, object>> { new("TransactionContext", transaction.TransactionId) }))
|
||||||
|
{
|
||||||
|
_logger.LogInformation("Begin transaction {TransactionId} for {CommandName} {Command}", transaction.TransactionId, typeName, request);
|
||||||
|
|
||||||
|
response = await next();
|
||||||
|
|
||||||
|
_logger.LogInformation("Commit transaction {TransactionId} for {CommandName}", transaction.TransactionId, typeName);
|
||||||
|
}
|
||||||
|
|
||||||
|
await transaction.CommitAsync();
|
||||||
|
});
|
||||||
|
|
||||||
|
return response ?? throw new ApplicationException($"Command {typeName} returned null response");
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "Error Handling transaction for {CommandName} {Request}", typeName, request);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,16 +1,48 @@
|
|||||||
// Copyright (c) HelloShop Corporation. All rights reserved.
|
// Copyright (c) HelloShop Corporation. All rights reserved.
|
||||||
// See the license file in the project root for more information.
|
// See the license file in the project root for more information.
|
||||||
|
|
||||||
|
using AutoMapper;
|
||||||
|
using HelloShop.OrderingService.Entities.Buyers;
|
||||||
|
using HelloShop.OrderingService.Entities.Orders;
|
||||||
|
using HelloShop.OrderingService.Infrastructure;
|
||||||
using HelloShop.OrderingService.Services;
|
using HelloShop.OrderingService.Services;
|
||||||
using MediatR;
|
using MediatR;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
|
||||||
namespace HelloShop.OrderingService.Commands.Orders
|
namespace HelloShop.OrderingService.Commands.Orders
|
||||||
{
|
{
|
||||||
public class CreateOrderCommandHandler : IRequestHandler<CreateOrderCommand, bool>
|
public class CreateOrderCommandHandler(OrderingServiceDbContext dbContext, IMapper mapper) : IRequestHandler<CreateOrderCommand, bool>
|
||||||
{
|
{
|
||||||
public Task<bool> Handle(CreateOrderCommand request, CancellationToken cancellationToken)
|
public async Task<bool> Handle(CreateOrderCommand request, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
Address address = mapper.Map<Address>(request);
|
||||||
|
|
||||||
|
IEnumerable<OrderItem> orderItems = mapper.Map<IEnumerable<OrderItem>>(request.OrderItems);
|
||||||
|
|
||||||
|
Buyer? buyer = await dbContext.Set<Buyer>().FindAsync([request.UserId], cancellationToken);
|
||||||
|
|
||||||
|
if (buyer == null)
|
||||||
|
{
|
||||||
|
buyer = new() { Id = request.UserId, Name = request.UserName };
|
||||||
|
await dbContext.AddAsync(buyer, cancellationToken);
|
||||||
|
await dbContext.SaveChangesAsync(cancellationToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
PaymentMethod? paymentMethod = await dbContext.Set<PaymentMethod>().SingleOrDefaultAsync(pm => pm.BuyerId == buyer.Id && pm.CardNumber == request.CardNumber, cancellationToken);
|
||||||
|
|
||||||
|
if (paymentMethod == null)
|
||||||
|
{
|
||||||
|
paymentMethod = new() { BuyerId = buyer.Id, Alias = request.CardAlias, CardNumber = request.CardNumber, SecurityNumber = request.CardSecurityNumber, CardHolderName = request.CardHolderName, Expiration = request.CardExpiration };
|
||||||
|
await dbContext.AddAsync(paymentMethod, cancellationToken);
|
||||||
|
await dbContext.SaveChangesAsync(cancellationToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
Order order = new(buyer.Id, address, orderItems) { PaymentMethodId = paymentMethod.Id };
|
||||||
|
|
||||||
|
await dbContext.AddAsync(order, cancellationToken);
|
||||||
|
await dbContext.SaveChangesAsync(cancellationToken);
|
||||||
|
|
||||||
|
return await Task.FromResult(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,6 +29,7 @@ namespace HelloShop.OrderingService.Extensions
|
|||||||
options.RegisterServicesFromAssembly(Assembly.GetExecutingAssembly());
|
options.RegisterServicesFromAssembly(Assembly.GetExecutingAssembly());
|
||||||
options.AddBehavior(typeof(LoggingBehavior<,>));
|
options.AddBehavior(typeof(LoggingBehavior<,>));
|
||||||
options.AddBehavior(typeof(ValidatorBehavior<,>));
|
options.AddBehavior(typeof(ValidatorBehavior<,>));
|
||||||
|
options.AddBehavior(typeof(TransactionBehavior<,>));
|
||||||
});
|
});
|
||||||
|
|
||||||
builder.Services.AddModelMapper().AddModelValidator();
|
builder.Services.AddModelMapper().AddModelValidator();
|
||||||
|
Loading…
Reference in New Issue
Block a user