Creating a sold-out handler

Let's start by creating a handler that manages the sold-out condition of a product in the cart service. First of all, we should proceed by adding the RabbitMQ.Client package to the Cart.Domain project by executing the following command:

dotnet add ./src/Cart.Domain package RabbitMQ.Client

We can continue by defining a class that represents the sold-out event that's used by the cart service in a new project that will contain all of the events. Therefore, we will proceed by creating a new ItemSoldOutEvent type, which represents a sold-out event:

using MediatR;

namespace Cart.Domain.Events
{
public class ItemSoldOutEvent : IRequest<Unit>
{
public string Id { get; set; }
}
}

The ItemSoldOutEvent type contains a reference to Id of the item that's sold out. The type will be used to deserialize the content of the queue into a strongly typed instance and send a message through the MediatR instance. As we did for the configurations of the catalog service, we will also need an analog class that represents the RabbitMQ configurations in the Cart.Infrastructure project:

namespace Cart.Infrastructure.Configurations
{
public class EventBusSettings
{
public string HostName { get; set; }
public string User { get; set; }
public string Password { get; set; }
public string EventQueue { get; set; }
}
}

The EventBusSettings type defined previously describes HostName of the RabbitMQ instance, User and Password of the user, and the EventQueue name to use to push messages. Furthermore, we can proceed by defining the mediator handler for consuming the ItemSoldOutEvent events by defining a new class in the Cart.Domain project:

using System;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Cart.Domain.Entities;
using Cart.Domain.Events;
using Cart.Domain.Repositories;
using MediatR;

namespace Cart.Domain.Handlers.Cart
{
public class ItemSoldOutEventHandler :
IRequestHandler<ItemSoldOutEvent>
{
private readonly ICartRepository _cartRepository;

public ItemSoldOutEventHandler(ICartRepository cartRepository)
{
_cartRepository = cartRepository;
}

public async Task<Unit> Handle(ItemSoldOutEvent @event,
CancellationToken cancellationToken)
{
var cartIds = _cartRepository.GetCarts().ToList();

var tasks = cartIds.Select(async x =>
{
var cart = await _cartRepository.GetAsync(new Guid(x));
await RemoveItemsInCart(@event.Id, cart);
});

await Task.WhenAll(tasks);

return Unit.Value;
}

private async Task RemoveItemsInCart(string itemToRemove,
CartSession cartSessionSession)
{
if (string.IsNullOrEmpty(itemToRemove)) return;

var toDelete = cartSessionSession?.Items?.Where(x =>
x.CartItemId.ToString() ==
itemToRemove).
ToList();

if (toDelete == null || toDelete.Count == 0) return;

foreach (var item in toDelete)
cartSessionSession.
Items?.Remove(item);

await _cartRepository.AddOrUpdateAsync(cartSessionSession);
}
}
}

The previous ItemSoldOutEventHandler class implements the IRequestHandler<T> interface that's provided by the MediatR package. This interface contains the Handle method, which is the main entry point of the handler. A new ItemSoldOutEventHandler instance will be executed when an event of the ItemSoldOutEvent type is received by the cart service. ItemSoldOutEventHandler depends on ICartRepository. Furthermore, the RemoveItemsInCart method retrieves all of the carts stored in our repository, and it removes the sold-out items every time it receives a message of the ItemSoldOutEvent type.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
52.14.168.56