using MediatR; using ZeroFramework.DeviceCenter.Infrastructure.Idempotency; namespace ZeroFramework.DeviceCenter.Application.Infrastructure { /// /// Provides a base implementation for handling duplicate request and ensuring idempotent updates, in the cases where /// a requestid sent by client is used to detect duplicate requests. /// public class IdentifiedCommandHandler(IMediator mediator, IRequestManager requestManager) : IRequestHandler, TResponse> where TRequest : IRequest { private readonly IMediator _mediator = mediator; private readonly IRequestManager _requestManager = requestManager; /// /// Creates the result value to return if a previous request was found /// protected virtual TResponse? CreateResultForDuplicateRequest() => default; /// /// This method handles the command. It just ensures that no other request exists with the same ID, and if this is the case /// just enqueues the original inner command. /// public async Task Handle(IdentifiedCommand command, CancellationToken cancellationToken) { if (await _requestManager.ExistAsync(command.Id)) { return CreateResultForDuplicateRequest() ?? throw new NotImplementedException(); } await _requestManager.CreateRequestForCommandAsync(command.Id); // Send the embeded business command to mediator so it runs its related CommandHandler return await _mediator.Send(command.Command, cancellationToken); } } }