Releases: jbogard/MediatR
10.0.1
10.0.0
This release adds support for IAsyncEnumerable<T>
. A new request type, IStreamRequest<T>
represents a request to create a stream, with a new handler type IStreamRequestHandler<TRequest, TResponse>
to handle. An example:
public class StreamPing : IStreamRequest<Pong>
{
public string? Message { get; init; }
}
public class PingStreamHandler : IStreamRequestHandler<StreamPing, Pong>
{
public async IAsyncEnumerable<Pong> Handle(StreamPing request,
[EnumeratorCancellation] CancellationToken cancellationToken)
{
yield return await Task.Run(() => new Pong { Message = request.Message + " Pang" }, cancellationToken);
}
}
Where the work inside of the handler would likely be calling some other streaming API, such as gRPC, EF Core streaming support, Dapper streaming etc.
There are also separate behaviors, with IStreamPipelineBehavior
that are separate from the normal IPipelineBehavior
.
With the addition of IAsyncEnumerable
, this release now targets netstandard2.1
exclusively.
There are some breaking API changes, called out in the 10.0 migration guide.
9.0.0
This release contains a small, but breaking change. In order to provide a simpler interface, the IMediator
interface is now split into two interfaces, a sender and publisher:
public interface ISender
{
Task<TResponse> Send<TResponse>(IRequest<TResponse> request, CancellationToken cancellationToken = default);
Task<object?> Send(object request, CancellationToken cancellationToken = default);
}
public interface IPublisher
{
Task Publish(object notification, CancellationToken cancellationToken = default);
Task Publish<TNotification>(TNotification notification, CancellationToken cancellationToken = default)
where TNotification : INotification;
}
public interface IMediator : ISender, IPublisher
{
}
The main motivation here is that sending should be a top-level concern of an application, but publishing can happen anywhere. This interface segregation should help catch design errors, where should never send requests from anywhere inside a request handler.
8.0.2
8.0.1
8.0.0
See announcement:
7.0.0
6.0.0
This release brings a slight breaking change to the Mediator
class. It adds a non-generic method overload to Publish
:
public interface IMediator
{
Task<TResponse> Send<TResponse>(IRequest<TResponse> request, CancellationToken cancellationToken = default);
+ Task Publish(object notification, CancellationToken cancellationToken = default);
Task Publish<TNotification>(TNotification notification, CancellationToken cancellationToken = default)
where TNotification : INotification;
}
And expands the publishing possibilities for the Mediator
class:
- protected virtual async Task PublishCore(IEnumerable<Task> allHandlers)
+ protected virtual async Task PublishCore(IEnumerable<Func<Task>> allHandlers)
{
foreach (var handler in allHandlers)
{
- await handler.ConfigureAwait(false);
+ await handler().ConfigureAwait(false);
}
If you've overridden the PublishCore
method, check out the publishing options section in the wiki for some examples.
This release targets net461
and netstandard2.0
and adds strong-naming to the assembly. net45
and netstandard1.3
were dropped.
5.1.0
This release changes the default behavior of awaiting an enumerable of Task
. Previous to this release, tasks where awaited using Task.WhenAll
. This causes problems in a variety of environments and situations that expect sequential ordering.
In this release, the default behavior for enumerables is to await in a foreach
, for:
Mediator.Publish
RequestPreProcessorBehavior
RequestPostProcessorBehavior
You can override the Mediator.Publish
behavior by overriding the virtual PublishCore
method, while the other two you can simply replace with your own implementation.
5.0.1
This release consolidates some interfaces and factories. The factory delegates are now just a single delegate, ServiceFactory
.
Additionally, the "void" IRequest
interface now inherits IRequest<Unit>
, and the IRequestHandler<T>
inherits IRequestHandler<T, Unit>
.