question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

IRequestPostProcessor executed multiple times

See original GitHub issue

I was originally using IPipelineBehavior to add pre and post hooks to a mediator pipeline but have then swapped out these to use IRequestPreProcessor and IRequestPostProcessor respectfully.

Unfortunately doing so causes my handlers to be executed twice. Contrary to the docs, I’m not registering them explicitly as they appear to be getting registered automatically.

MediatR is registered like so (ASP.NET Core 2.2):

            services.AddMediatR(typeof(PaymentsRegistry).Assembly);
            services.AddTransient(typeof(IPipelineBehavior<,>), typeof(LoggingMediatorBehavior<,>));
            services.AddTransient(typeof(IPipelineBehavior<,>), typeof(SequentialProcessingBehavior<,>));

Example of one my behaviours:

    internal class PaymentRequestedDispatcher : IRequestPreProcessor<AuthorizeCardPayment>
    {
        private readonly IMediator _mediator;
        private readonly ILogger _logger;

        public PaymentRequestedDispatcher(IMediator mediator, ILogger logger)
        {
            _mediator = mediator ?? throw new ArgumentNullException(nameof(mediator));
            _logger = logger ?? throw new ArgumentNullException(nameof(logger));
        }

        public async Task Process(AuthorizeCardPayment command, CancellationToken cancellationToken)
        {
            if (command is null)
                throw new ArgumentNullException(nameof(command));

            _logger.Debug("Executing Payment Requested Dispatcher for Payment {PaymentId}", command.PaymentId.ToString());

            var requested = new Requested(

            );

            await _mediator.Publish(requested, cancellationToken);
        }
    }

From my logs I am seeing all of the pre/post handlers getting executed twice:

2019-10-29 18:21:51 DBG Computing Hash of ApiKey "completed" in 37.5 ms
2019-10-29 18:21:51 DBG Retrieving ApiKeyDetails from Couchbase "completed" in 71.4 ms
2019-10-29 18:21:51 DBG Validating type "PaymentRequest<CardSource>" using "PaymentRequestWithSourceValidator<CardSource, CardSourceValidator>" "completed" in 1.4 ms
2019-10-29 18:21:52 DBG Storing card details in Vault "completed" in 134.3 ms
2019-10-29 18:21:52 DBG Executing Payment Requested Dispatcher for Payment "pay_p57sma5ssgkevhzcgccpanqxc4"
2019-10-29 18:21:52 DBG Inserting GetPayment Document in Couchbase "completed" in 18.6 ms
2019-10-29 18:21:52 DBG Creating new publisher for stream "Payment-pay_p57sma5ssgkevhzcgccpanqxc4"
2019-10-29 18:21:52 DBG Executing Payment Requested Dispatcher for Payment "pay_p57sma5ssgkevhzcgccpanqxc4"
2019-10-29 18:21:52 INF Found credentials using the AWS SDK's default credential search
2019-10-29 18:21:52 DBG Inserting GetPayment Document in Couchbase "completed" in 5.3 ms
2019-10-29 18:21:52 DBG Queueing event to batch for "Payment-pay_p57sma5ssgkevhzcgccpanqxc4"
2019-10-29 18:21:52 DBG Queueing event to batch for "Payment-pay_p57sma5ssgkevhzcgccpanqxc4"
2019-10-29 18:21:52 DBG Retrieving Merchant from Couchbase "completed" in 26.5 ms
2019-10-29 18:21:52 DBG Retrieving Acquirer service configuration from Couchbase "completed" in 17.3 ms
2019-10-29 18:21:52 DBG Generated acquirer transaction ID 41001 for payment transaction ID 5ea33cbf-98f0-440a-ab23-cef0c774e94a
2019-10-29 18:21:52 DBG Queueing event to batch for "Payment-pay_p57sma5ssgkevhzcgccpanqxc4"
2019-10-29 18:21:52 INF Processing "4" with acquirer: "cko-visa" "completed" in 184.1 ms
2019-10-29 18:21:52 DBG Writing PaymentRecord to Couchbase "completed" in 53.6 ms
2019-10-29 18:21:52 DBG Executing Authorization Result Dispatcher for Payment "pay_p57sma5ssgkevhzcgccpanqxc4"
2019-10-29 18:21:52 DBG Updating GetPayment Document in Couchbase "completed" in 40.6 ms
2019-10-29 18:21:52 DBG Queueing event to batch for "Payment-pay_p57sma5ssgkevhzcgccpanqxc4"
2019-10-29 18:21:52 DBG Executing Auto-Capture Handler for Payment "pay_p57sma5ssgkevhzcgccpanqxc4"
2019-10-29 18:21:52 DBG Retrieving URL for SQS queue "default" "completed" in 217.8 ms
2019-10-29 18:21:53 DBG Sending message "CapturePayment" to SQS "completed" in 45.7 ms
2019-10-29 18:21:53 DBG Handling "Enqueue" with Mediator "completed" in 285.3 ms
2019-10-29 18:21:53 DBG Queueing event to batch for "Payment-pay_p57sma5ssgkevhzcgccpanqxc4"
2019-10-29 18:21:53 DBG Executing Auto-Void Handler for Payment "pay_p57sma5ssgkevhzcgccpanqxc4"
2019-10-29 18:21:53 DBG Handling "AuthorizeCardPayment" with Mediator "completed" in 831.1 ms
2019-10-29 18:21:53 DBG Executing Authorization Result Dispatcher for Payment "pay_p57sma5ssgkevhzcgccpanqxc4"
2019-10-29 18:21:53 DBG Updating GetPayment Document in Couchbase "completed" in 1.3 ms
2019-10-29 18:21:53 DBG Executing Auto-Capture Handler for Payment "pay_p57sma5ssgkevhzcgccpanqxc4"
2019-10-29 18:21:53 DBG Queueing event to batch for "Payment-pay_p57sma5ssgkevhzcgccpanqxc4"
2019-10-29 18:21:53 DBG Sending message "CapturePayment" to SQS "completed" in 5.4 ms
2019-10-29 18:21:53 DBG Handling "Enqueue" with Mediator "completed" in 5.9 ms
2019-10-29 18:21:53 DBG Executing Auto-Void Handler for Payment "pay_p57sma5ssgkevhzcgccpanqxc4"
2019-10-29 18:21:53 DBG Queueing event to batch for "Payment-pay_p57sma5ssgkevhzcgccpanqxc4"
2019-10-29 18:21:53 DBG Handling "RequestPayment<FullCardSource>" with Mediator "completed" in 1078.5 ms
2019-10-29 18:21:53 DBG Handling "PaymentRequest<CardSource>" with Mediator "completed" in 1177.7 ms
2019-10-29 18:21:53 INF HTTP "POST" "/payments" responded 201 in 2871.4427 ms

Also am I right that the only way to control the order of behaviours is if I use IPipelineBehavior and register them explicitly?

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Comments:10 (4 by maintainers)

github_iconTop GitHub Comments

2reactions
lilasquaredcommented, Jan 24, 2020

if you are using AddMediatR, that function already adds the pre and post processors, you do not need to manually register them using AddTransient in the Core Package. Just remove the manual registration and they won’t get registered multiple times.

0reactions
levyhnunescommented, Apr 23, 2020

I had the same problem, and it was precisely because I registered AddMediatR separately, this worked.

var assemblies = new System.Reflection.Assembly[]
{
 AppDomain.CurrentDomain.Load("Core"),
 AppDomain.CurrentDomain.Load("Notifications"),
 AppDomain.CurrentDomain.Load("Domain")
});

services.AddMediatR(assemblies);
Read more comments on GitHub >

github_iconTop Results From Across the Web

How do I register a MediatR post processor - net core
Thanks for looking into this. registering the behavior as you suggest makes the Posthandler run, but it executes twice. Any ide why? –...
Read more >
Sharing Context in MediatR Pipelines
Basically, I'm recreating a lot of existing functional patterns in an OO language, using dependency injection. Side note - it's possible to do ......
Read more >
MediatR Pipeline Examples
So when processing requests gets more complicated, we often rely on a mediator pipeline to provide a means for these extra behaviors.
Read more >
[Dot Net Core](Graphic series ) 17. MediatR — PreProcess ...
Suppose we take the example of executing the following: ... will inject IRequestPostProcessor<TRequest, TResponse> entity.
Read more >
Mediator and CQRS Design Patterns
MediatR exposes two types of messages, request/response and notifications. The first model executes a single handler, while the second allows multiple handlers ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found