Skip to content
This repository has been archived by the owner on Apr 14, 2023. It is now read-only.

Composite commands #92

Closed
quentin-villevieille opened this issue Nov 20, 2019 · 12 comments
Closed

Composite commands #92

quentin-villevieille opened this issue Nov 20, 2019 · 12 comments
Assignees
Milestone

Comments

@quentin-villevieille
Copy link

Hi,
I stumbled upon an interesting article yesterday about composite commands. Basically a composite command is a command container, each command being a container (or not). In the article, ICommand defines an Execute method to implement in deriving classes.
But as far as I know, this can't be achieved with Kledex because of the way the commands work (correct me if I'm wrong). Maybe there's something I'm missing out somewhere ?

@lucabriguglia
Copy link
Owner

I like the idea behind it but not the suggested solution. If I understand it correctly, Execute() should be the equivalent of a Handle in a command handler (please correct me if I'm wrong). If I am right, how would you deal with dependency injection?

I think you can achieve something similar with Kledex using the event handlers. A command handler produces one or more events that can be automatically sent to the relative event handlers. You might create a sequence of commands and events to achieve the same result.

But a better solution may be a saga which is not currently supported in Kledex but it's something that I'd like to add.

@lucabriguglia
Copy link
Owner

The more I think about the idea and the more I like it. It should not be too complicated to implement something similar and reusing the current flow. I just need to find a clean way to pass a command response to the next command in the sequence.

@lucabriguglia
Copy link
Owner

I think we just need a new command handler interface with a handle method that accepts 2 parameters: command and command response of the previous command handler in the sequence.

@lucabriguglia lucabriguglia added this to the Kledex 2.3 milestone Nov 20, 2019
@lucabriguglia
Copy link
Owner

lucabriguglia commented Nov 21, 2019

I have implemented it quite easily. You can see the progress in this branch: https://github.com/lucabriguglia/Kledex/tree/issue-92-composite-commands

There is a sample console app to run: Kledex.Sample.CommandSequence.

@lucabriguglia
Copy link
Owner

This is how to use the new feature:

await dispatcher.SendAsync(
  new FirstCommand(), 
  new SecondCommand(), 
  new ThirdCommand());

Each command passes its response to the next one in the sequence.

And this is how to get a final result from the last command handler:

var result = await dispatcher.SendAsync<string>(
  new FirstCommand(), 
  new SecondCommand(), 
  new ThirdCommand());

@quentin-villevieille
Copy link
Author

Nice ! I've just tried it, it works great.
But I'm wondering if the controller has to know about the command sequence. I believe the sequence definition must be in the domain layer, and the controller would just call it from the domain.

@lucabriguglia
Copy link
Owner

Good point, should we create a separate class that holds the sequence?

@quentin-villevieille
Copy link
Author

quentin-villevieille commented Nov 21, 2019

Yeah, I think so. We could name it SequenceCommand or somethinkg like that :)

@lucabriguglia
Copy link
Owner

lucabriguglia commented Nov 21, 2019

Now we have:

public class SampleCommandSequence : CommandSequence
{
    public SampleCommandSequence()
    {
        AddCommand(new FirstCommand());
        AddCommand(new SecondCommand());
        AddCommand(new ThirdCommand());
     }
 }

And:

await dispatcher.SendAsync(new SampleCommandSequence());

Or:

var result = await dispatcher.SendAsync<string>(new SampleCommandSequence());

@quentin-villevieille
Copy link
Author

That's spot on, thanks mate !

lucabriguglia pushed a commit that referenced this issue Nov 23, 2019
@lucabriguglia
Copy link
Owner

Released in version 2.3

@lucabriguglia
Copy link
Owner

Refer to #101 for new functionalities

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

No branches or pull requests

2 participants