Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CommandProcessor ignores handler with a TResult #86

Closed
seif opened this issue Jan 23, 2013 · 10 comments
Closed

CommandProcessor ignores handler with a TResult #86

seif opened this issue Jan 23, 2013 · 10 comments
Milestone

Comments

@seif
Copy link
Member

seif commented Jan 23, 2013

Just looking at the code in

public void Process<TCommand>(TCommand command) where TCommand : ICommand
{
Validator.ValidateObject(command, new ValidationContext(command, null, null), true);
var handlers = ServiceLocator.Current.GetAllInstances<ICommandHandler<TCommand>>();
if (handlers == null || !handlers.Any())
{
throw new CommandHandlerNotFoundException(typeof(TCommand));
}
foreach (var handler in handlers)
{
handler.Handle(command);
}
}

and
var handlers = ServiceLocator.Current.GetAllInstances<ICommandHandler<TCommand, TResult>>();

I think there would be a problem where if the caller didn't care about the result, and just wanted to fire the command and there was a handler registered for the command but implementing ICommandHandler<in TCommand, out TResult>, then that handler would not be called.

Do we want it to be called? What should we do for the other way around? where the user cared for the result and called the overload with the TResult, handlers that implement the ICommandHandler would not be triggered, should they be called but without adding any result to the return Enumeration?

@sandord
Copy link

sandord commented Jan 23, 2013

I had a discussion about multiple command handlers with a colleague a few years ago. He stated that it doesn't make sense to have multiple command handlers handle the same command. One of his arguments were that you have no idea in which order the command handlers will be executed. I tend to agree with this.

Can you give a real world example where implementing multiple command handlers (which will be executed in no particular order) makes sense?

If not, we may consider simplifying the whole thing by supporting only one command handler per command. Knowing that there is only one registered command handler (which should be asserted), we can now have the command processor discard the result if the user didn't ask for one and throw an exception when he asks for a result while there isn't.

@seif
Copy link
Member Author

seif commented Jan 23, 2013

I can't think of a real world example, but the code as it currently stands allows it, which is not right. +1 for having only 1 registered command handler and following @sandord in the last paragraph. If we want to do multiple things when a command is fired, then we should publish an event, and have event handlers to do the other work.

sandord added a commit that referenced this issue Feb 13, 2013
…ee issue #86) and updated the command handler to have virtual members in order to improve extensibility.
@sandord
Copy link

sandord commented Feb 20, 2013

Perhaps we should get rid of the overload that takes a result handler. To my taste, it is superfluous since only one result instance will be available and it can simply be returned as a method result.

@seif
Copy link
Member Author

seif commented Feb 20, 2013

I see your point about the overload with the delegate, I guess it is a matter of preference and my preference is not to have a result at all :) but there was quite a few people who wanted results from command handler which is why it was added.

Let's give someone a chance to object before doing it, give it a week or so.

@sandord
Copy link

sandord commented Feb 20, 2013

Yes but it was added mainly because multiple results could be returned due to the former possibility to have multiple command handlers for a single command. Now that we have only one result at most, there is no need to have the overload since the method can simply return the return value. So the real reason I'd like to see it go is because it is redundant. But sure, I'll hold my breath for a while :)

@seif seif added this to the 4.0 milestone Apr 26, 2015
@seif
Copy link
Member Author

seif commented Apr 26, 2015

And add docs for command processing/dispatching and event handling.

@cd21h
Copy link

cd21h commented Aug 15, 2015

I'd rather replace command processor with https://github.com/jbogard/MediatR.
For current version we can mark it as obsolete.
@seif, What do you think?

@seif
Copy link
Member Author

seif commented Sep 1, 2015

@Shatl sorry for late reply, was on holiday and then needed to look at the code for MediatR and see what it does.

I was worried about that the async stuff is actually spinning up tasks, but it leaves that to the implementors. The only issue I see is the lack of a Send that doesn't have a reply. i.e. MediatR only handles the event publishing and request/response style not a trigger of a command or a Send without a response.

Ignore the above, did some more digging in the code, and saw https://github.com/jbogard/MediatR/blob/master/src/MediatR/Unit.cs and the abstract class of RequestHandler we'd need to use that in an example for TResponse showing how to use the mediator with it.

I don't see a reason why not to depend on it, it doesn't have any dependencies that would conflict with ours. :)

@cd21h
Copy link

cd21h commented Nov 23, 2015

@seif, I believe we can close the issue then. For users who want to use Command/Query pattern, let's recommend https://github.com/jbogard/MediatR .

@seif
Copy link
Member Author

seif commented Nov 23, 2015

Sure, wanna raise a ticket to delete the command processing code?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants