订单创建命令处理程序
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.
|
||||
// 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 MediatR;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
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.AddBehavior(typeof(LoggingBehavior<,>));
|
||||
options.AddBehavior(typeof(ValidatorBehavior<,>));
|
||||
options.AddBehavior(typeof(TransactionBehavior<,>));
|
||||
});
|
||||
|
||||
builder.Services.AddModelMapper().AddModelValidator();
|
||||
|
Loading…
Reference in New Issue
Block a user