Releases: LuckyPennySoftware/MediatR
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.PublishRequestPreProcessorBehaviorRequestPostProcessorBehavior
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>.
4.1.0
4.0.1
The last major release of MediatR brought a simplification in design. Instead of having several different IRequest types and IRequestHandler implementations with several flavors, MediatR would try at runtime to determine how a single IRequest should resolve to different IRequestHandler implementations (synchronous, async, async with a cancellation token). In practice, this proved problematic as not all containers support this sort of 'try-resolve' behavior. MediatR relied on try...catch to resolve, which can work, has unintended side effects.
MediatR 4.0 consolidates these design decisions. We'll still have a single IRequest type, but will now have only a single IRequestHandler interface. This simplifies the registrations quite a bit:
// Before (StructureMap)
cfg.Scan(scanner =>
{
scanner.AssemblyContainingType<Ping>();
scanner.ConnectImplementationsToTypesClosing(typeof(IRequestHandler<,>));
scanner.ConnectImplementationsToTypesClosing(typeof(IRequestHandler<>));
scanner.ConnectImplementationsToTypesClosing(typeof(IAsyncRequestHandler<,>));
scanner.ConnectImplementationsToTypesClosing(typeof(IAsyncRequestHandler<>));
scanner.ConnectImplementationsToTypesClosing(typeof(ICancellableAsyncRequestHandler<,>));
scanner.ConnectImplementationsToTypesClosing(typeof(ICancellableAsyncRequestHandler<>));
scanner.ConnectImplementationsToTypesClosing(typeof(INotificationHandler<>));
scanner.ConnectImplementationsToTypesClosing(typeof(IAsyncNotificationHandler<>));
scanner.ConnectImplementationsToTypesClosing(typeof(ICancellableAsyncNotificationHandler<>));
});
// After
cfg.Scan(scanner =>
{
scanner.AssemblyContainingType<Ping>();
scanner.ConnectImplementationsToTypesClosing(typeof(IRequestHandler<,>));
scanner.ConnectImplementationsToTypesClosing(typeof(IRequestHandler<>));
scanner.ConnectImplementationsToTypesClosing(typeof(INotificationHandler<>));
});This new default interface is the previous ICancellableAsyncRequestHandler interface:
public interface IRequestHandler<in TRequest, TResponse>
where TRequest : IRequest<TResponse>
{
Task<TResponse> Handle(TRequest request, CancellationToken cancellationToken);
}
public interface IRequestHandler<in TRequest>
where TRequest : IRequest
{
Task Handle(TRequest message, CancellationToken cancellationToken);
}Instead of multiple interfaces, MediatR 4.0 (re)introduces helper base classes:
- RequestHandler - for synchronous actions
- AsyncRequestHandler - for async actions that ignore the cancellation token
With the simplified interfaces, it's much less possible to "forget" a registration in your container.
Another small but breaking change is the behavior pipeline and pre-processor now have the cancellation token as part of the interface.
Both the MediatR and MediatR.Extensions.Microsoft.DependencyInjection packages are released with the simplified API.
Since these are breaking changes to the API (hence the major version bump), migration to the new API is manual. However, to ease the transition, you can follow the 3.0 to 4.0 migration guide. I've also updated the docs to walk through the new classes, and the samples include the updated registrations for the major containers out there:
- Microsoft DI
- Autofac
- DryIoc
- LightInject
- Ninject
- Simple Injector
- StructureMap
- Unity
- Windsor
A big move for MediatR to break the API, but necessary to remove the complexity in multiple interfaces and registration. The only other option would be to make MediatR responsible for all registration and wiring, which is more than I want MediatR to do. The design goal of MediatR is to lean on the power of DI containers for registration, and MediatR merely resolves its interfaces.
3.0.1
3.0.0
This release brings a major overhaul to the API of MediatR. The IMediator interface is now async-only, supporting optional cancellation tokens. The 'Async' postfix was not added onto the Send/Publish method names as there are no sync overloads.
On the handler side, you no longer need to build specific request/response types for sync/async. All request/notification types are IRequest or INotification. Instead, MediatR finds the appropriate handler implementation based on IRequestHandler, IAsyncRequestHandler and ICancellableAsyncRequestHandler.
The base class for RequestHandler is gone as well, with just the interfaces remaining.
New in this release are built-in support for pipelines through behaviors, which you can find more information about in the wiki.