jbogard / MediatR

Simple, unambitious mediator implementation in .NET
Apache License 2.0
11.1k stars 1.18k forks source link

Please implement handlers by name and/or enum type #383

Closed codematrix closed 5 years ago

codematrix commented 5 years ago

Hi I was forced by some principle engineer to use MediatR rather than my Autofac dependancy injection factory pattern. Here's my case scenario:

I have 20 handlers that all receive the same request object type (envelope) and within that object there's a type enum property that distinguishes the data type contained in side the envelope.

Can you implement a method to support the following?

_mediatr.Send(MyEnumType.Type1, commonRequest1); // calls handler1 _mediatr.Send(MyEnumType.Type2, commonRequest1); // calls handler2 _mediatr.Send(MyEnumType.Type3, commonRequest1); // calls handler3

Or by string name

_mediatr.Send("name1", commonRequest1); // calls handler3 _mediatr.Send("name2", commonRequest1); // calls handler2 _mediatr.Send("name2", commonRequest1); // calls handler3

Using MediatR as is for the my domain problem requires me to create 20 different request classes where I only need one. Secondly, I also need a massive case statement to distinguish the correct request type and then call the Send method.

codematrix

jbogard commented 5 years ago

No, because this would require all containers to support it, and be a breaking change to the factory delegate. Maybe you can create an extension method, or extend IMediator yourself?

codematrix commented 5 years ago

Good idea. I did exactly that. I just don't want to carry the weight of this code inside my code base, hence I was hoping it was something that you already support or would have implemented.

Maybe when I get a chance I'll do a PR to show you what I have implemented.

Thanks for your feedback.

syska commented 5 years ago

@codematrix

Not that I have a solution, but since the "principle engineer" have forced you to use something that don't support what you want ... what does he have to say?

Just out of curiosity, i'm wondering why you have 20 handlers but can use almost the same request(apart from the enum) ... what does these handlers do? I guess it's domain specific ... but i'm always eager to learn and see what other people are facing in the development ...

codematrix commented 5 years ago

@syska

Well, I'm just a contractor who brings a lot of experience to the table (30 years). This engineer is overseeing our project, with 1/3 of the experience I have. Not saying he's not a smart guy. He's just using the wrong tool and design pattern for the job. I need a screwdriver not a sledgehammer :) If I have to twist and work around the tool just to make it work in my particular use case, then it's not the right tool. Not saying MediatR isn't a great framework/design pattern, in my particular case it's making things more complex then they need be.

My use case

We have a lot of different event types (22 for now) that are packaged in an envelope and are placed on an activity queue. Each event has to be placed on the queue in sequence and must be processed in sequence. This is a must!! The data in the package differs based on event type. For example, something like this:

{ "event-type": "Event-Clock", "data": {…} <--- specific clock data, if the event type was different, then the data property will be different }

Because I must keep things in sequence I can only have one consumer of these message types - the top level control, the consumer, does the following:

  1. Read the message off the queue
  2. Check the type and create the handler (through DI Factory) that knows how handle this type of event

In Autofac, I can register different implementations of each handler as such, by name:

builder.RegisterType(ClockHandler).Named("Event-Clock").As(IHandle); builder.RegisterType(PickOrderHandler).Named("Event-PickOrder").As(Handler); builder.RegisterType(WMSHandler).Named("Event-WMS").As(IHandler);

then create the handler like this:

var handler = _dependencyFactory.Create(IHandler)(pagecke.EventType.ToString()); handler.Process(package);

Now I got something similar working with MediatR, but man I had to create so much useless code and added complexity to make it work similar to what I had before. I don't want the top level controller to know anything about event types. As more types are added to the mix, the top level controller doesn't have to change. Just a new handler for that event type will be added.

That's my rant ;)

syska commented 5 years ago

@codematrix

Thanks for sharing and taking the time to to explain the business logic behind.