gautema / CQRSlite

A lightweight framework to help creating CQRS and Eventsourcing applications in C#
Other
1.1k stars 266 forks source link

Allow registration of specific message handlers #65

Closed binarymash closed 6 years ago

binarymash commented 6 years ago

Hey @gautema,

Thanks for the effort you've put into CQRSlite. I've been using it for the last few months on a personal project and it's saved me a lot of time and effort. However, one thing that caused me some pain was how handlers are registered in RouteRegistrar. I have a suggestion for how this could be improved.

At the moment, the only option available is to register all the handlers in the same assembly as message type(s) I pass into RouteRegistrar.Register(...). This causes me problems because, in my use case, I don't want to register all the handlers in my code; I have a number of different handlers that might or might not be used, depending on the particular configuration of my code. I want to choose exactly which handlers I want to register. At the moment, the only option I have using is to split my handlers into multiple different assemblies.

To work around this limitation, I implemented my own code to allow me to explicitly pass in the handlers I want to register. So, now I can do this...

var handlers = new List<Type>(){
  // the message handlers I want to register
}

myRouteRegistrar.RegisterHandlers(handlers)

My implementation is much more complex than it ought to be; some of the registration code in CQRSlite is internal, so I need to use reflection and also copy and paste some of the code into my own project.

Implementing this directly in CQRSlite would be much simpler. I envisage that we'd make the following changes to RouteRegistrar:

  1. Mark RouteRegistrar.Register(params Type[] typesFromAssemblyContainingMessages) as obsolete
  2. Add a new method, RouteRegistrar.RegisterAllHandlersInSameAssemblyAs(params Type[] typesFromAssemblyContainingMessages) that behaves the same as the current RouteRegistrar.Register(...)
  3. Add a new method, RouteRegistrar.RegisterHandlers(params Type[] messageHandlers) that registers the specific handlers passed in.

Is this something that you think would be useful to get into the CQRSlite code base? If so, I'll look at implementing this.

gautema commented 6 years ago

Hi, and thanks for the feedback.

I have always just though of the RouteRegistar as a convenient way to register all at the same time. In your case, I would look at just registering them directly on the Router manually. If that becomes to cumbersome, I guess don't think adding a new method in the RouteRegistar would do any harm. I have to think a bit about the renaming and deprecation as I'd like to avoid it if possible. If you make pull request for it with tests, I can get it in to the code during next week.

binarymash commented 6 years ago

Hmm.. I wonder if I've misunderstood the registration process and made things more complex than it needs to be :)

Ok, let me check my code - I'll get back to you.

binarymash commented 6 years ago

Ok, I've looked through the code... There's quite a lot of boilerplate code to register each handler - basically copying much of RouteRegistrar.InvokeHandler to create the delegates to pass into IHandlerRegistrar.RegisterHandler.

So, I think it's worth having something in CQRSlite... I've had a go at implementing it, and it's actually a very small change. Seems to work ok for me, I'll create a pull request shortly.

gautema commented 6 years ago

Fix in 0.20.0