Closed DanTm99 closed 1 year ago
@jbogard Is there a good example of how to control the execution order of pre/post processor behaviors when you have multiple? Perhaps one could be added to the wiki.
No, I don't have a good example of that. Perhaps that needs to be exposed explicitly in the API, some other folks have also had problems of the order of auto-registered items.
One possiblity could be cfg.AddPreProcessor
and have cfg.AddPostPreccessor
, heh, this will cause breaking changes.
Another way around could be to declare the order itself by introducing a public int Order {get; }
property.
This looks a bit weird to me, but it should work without introducing breaking changes.
This is from PreProc source code, see comments:
namespace MediatR.Pipeline;
public class RequestPreProcessorBehavior<TRequest, TResponse> : IPipelineBehavior<TRequest, TResponse>
where TRequest : notnull
{
private readonly IEnumerable<IRequestPreProcessor<TRequest>> _preProcessors;
public RequestPreProcessorBehavior(IEnumerable<IRequestPreProcessor<TRequest>> preProcessors)
=> _preProcessors = OrderPreprocessors(preProcessors); // Orders the prepocessors
// only if any of those declares a different value than zero
// to keep compatiblity with existing implementations;
public async Task<TResponse> Handle(TRequest request, RequestHandlerDelegate<TResponse> next, CancellationToken cancellationToken)
{
foreach (var processor in _preProcessors)
{
await processor.Process(request, cancellationToken).ConfigureAwait(false);
}
return await next().ConfigureAwait(false);
}
private static IEnumerable<IRequestPreProcessor<TRequest>> OrderPreprocessors(
IEnumerable<IRequestPreProcessor<TRequest>> preProcessors)
{
if (preProcessors.All(preProcessor => proProcessor.Order == 0)
{
return preProcessors; // backward compatiblity
}
return preProcessors.OrderBy(p => p.Order);
}
}
Potential issues:
Order = -1
to a given PreProcessor, now he might have unexpected result with the other ones having the default value (which is zero).Order = 1
.Well I don't use pre and post processors anyway :D.
I think it isn't just the auto-registration, it's that the code will add the interface if it already exists: https://github.com/jbogard/MediatR/blob/master/src/MediatR/Registration/ServiceRegistrar.cs#L21
I can't remember why the code does this though.
When registering
IRequestPreProcessor
s andIRequestPostProcessor
s implicitly like the example in the readme:is it possible to specify the order in which they're run when there are multiple preprocessors, or multiple post processors? There doesn't seem to be anything in the wiki that allows for this.
Currently if I register them explicitly:
the preprocessors and the postprocessors run twice, due to them already having been registered implicitly.