Renamed SendOrThrowAsync and SendOrNotFoundAsync extension methods for IMediator to GetOrThrow for ISender, following MediatR best practices. Updated all usages, XML docs, and tests to use ISender and the new method names. Replaced StubMediator with StubSender in tests. Functionality remains the same, but code now aligns with modern MediatR conventions.
54 lines
3.1 KiB
C#
54 lines
3.1 KiB
C#
using System.Collections;
|
|
using DigitalData.Core.Exceptions;
|
|
using MediatR;
|
|
|
|
namespace EnvelopeGenerator.Application.Common.Extensions;
|
|
|
|
/// <summary>
|
|
/// Extension methods for <see cref="IMediator"/> that enforce non-null and non-empty responses.
|
|
/// </summary>
|
|
public static class MediatorExtensions
|
|
{
|
|
/// <summary>
|
|
/// Sends a request via MediatR and throws a custom exception produced by <paramref name="exceptionFactory"/>
|
|
/// when the response is <c>null</c> or an empty collection.
|
|
/// </summary>
|
|
/// <typeparam name="TResponse">The expected response type.</typeparam>
|
|
/// <typeparam name="TException">The exception type to throw.</typeparam>
|
|
/// <param name="sender">The mediator instance.</param>
|
|
/// <param name="request">The MediatR request whose response may be <c>null</c>.</param>
|
|
/// <param name="exceptionFactory">A factory that creates the exception to throw when the response is absent.</param>
|
|
/// <param name="cancel">Cancellation token.</param>
|
|
/// <returns>A guaranteed non-null <typeparamref name="TResponse"/>.</returns>
|
|
/// <exception cref="Exception">The exception produced by <paramref name="exceptionFactory"/>.</exception>
|
|
public static async Task<TResponse> GetOrThrow<TResponse, TException>(this ISender sender, IRequest<TResponse?> request, Func<TException> exceptionFactory, CancellationToken cancel = default)
|
|
where TException : Exception
|
|
{
|
|
if (await sender.Send(request, cancel) is TResponse res)
|
|
{
|
|
if (res is not string && res is IEnumerable enumerable && !enumerable.Cast<object>().Any())
|
|
throw exceptionFactory();
|
|
|
|
return res;
|
|
}
|
|
|
|
throw exceptionFactory();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sends a request via MediatR and throws <see cref="NotFoundException"/> when the response is <c>null</c> or an empty collection.
|
|
/// </summary>
|
|
/// <typeparam name="TResponse">The expected response type.</typeparam>
|
|
/// <param name="sender">The mediator instance.</param>
|
|
/// <param name="request">The MediatR request whose response may be <c>null</c>.</param>
|
|
/// <param name="exceptionMessage">Optional message for the <see cref="NotFoundException"/>.</param>
|
|
/// <param name="cancel">Cancellation token.</param>
|
|
/// <returns>A guaranteed non-null <typeparamref name="TResponse"/>.</returns>
|
|
/// <exception cref="NotFoundException">Thrown when the response is <c>null</c> or an empty collection.</exception>
|
|
public static async Task<TResponse> GetOrThrow<TResponse>(this ISender sender, IRequest<TResponse?> request, string? exceptionMessage, CancellationToken cancel = default)
|
|
=> await sender.GetOrThrow(request, () => new NotFoundException(exceptionMessage ?? $"The requested resource of type {typeof(TResponse).Name} was not found."), cancel);
|
|
|
|
/// <inheritdoc cref="GetOrThrow{TResponse}(ISender, IRequest{TResponse}, string, CancellationToken)"/>
|
|
public static async Task<TResponse> GetOrThrow<TResponse>(this ISender sender, IRequest<TResponse?> request, CancellationToken cancel = default)
|
|
=> await sender.GetOrThrow(request, null, cancel);
|
|
} |