MediatR icon indicating copy to clipboard operation
MediatR copied to clipboard

MediatR + Autofac NotificationHandler decorator pattern strange behaviour.

Open GianlucaLocri opened this issue 6 months ago • 6 comments

Hi, I'm having a very strange issue with decorator pattern using MediatR (12.4.0) and Autofac (8.0.0) but I really cannot understand wether the problem is concerning Autofac, MediatR or (more probably) my code...

Basically I have a custom wrapper around INotification:

// My custom notification wrapping the event
public interface IEventNotification<TEvent> : INotification
    where TEvent : IEvent
{
    TEvent Event { get; init; }
}

that is handled by this interface

// The custom Notification Handler.
public interface IEventNotificationHandler<TEvent> : INotificationHandler<IEventNotification<TEvent>>
        where TEvent : IEvent
{
}

My application will (very simplified) raise events. These events (whose implementations are known) are handled by some handlers. In some cases there are multiple handlers per event.

Now my code is working as expected until I introduce a decorator for the event handlers like this one

public class CustomNotificationHandlerDecorator<TDomainEvent> : IEventNotificationHandler<TDomainEvent>
    where TDomainEvent : IEvent
{
    private readonly INotificationHandler<IEventNotification<TDomainEvent>> _decorated;

    public CustomNotificationHandlerDecorator(IEventNotificationHandler<TDomainEvent> decorated)
    {
        _decorated = decorated;
    }

    public Task Handle(IEventNotification<TDomainEvent> notification, CancellationToken cancellationToken)
    {
        Console.WriteLine("I am the custom decorator!");
        _decorated.Handle(notification, cancellationToken);
		Console.WriteLine("Decorator job completed\n");
        return Task.CompletedTask;
    }
}

At this point, for a given event, the decorator is applied only to one of the declared handlers and the handlers itself is called multiple times!

This is somewhat difficult to explain, so I crafted a fully functional but yet simple example on dotnetfiddle: https://dotnetfiddle.net/5sIGzj

As you can see, only the SecondEventNotificationHandler is called (and decorated) twice. If the line 155 builder.RegisterGenericDecorator(typeof(CustomNotificationHandlerDecorator<>),typeof(INotificationHandler<>)); is commented out, the two event handlers are called as expected, (but the decorator is obviously not called).

I am struggling with this for several days and I really cannot get my head around... Thanks for the support and for your amazing work!

GianlucaLocri avatar Aug 12 '24 21:08 GianlucaLocri