HiveBrain v1.2.0
Get Started
← Back to all entries
patterncsharpMinor

"CommandBus" with Handlers & Observers

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
withobservershandlerscommandbus

Problem

I'm looking for a very simple (at first sight) CommandBus, which will handle some ICommand publication. The CommandBus implementation will find the appropriate IHandler to Execute the Command and then Notify some possible IObservers.

My first step is to make it work, I've chosen to use a synchronous dependency injection pattern which I may extends in the future, maybe using a real ServiceBus with some asynchronous capability.

Here is the abstract definition:

public interface ICommandBus
{
    TResult Publish(TCommand command)
        where TResult : ICommandResult
        where TCommand : ICommand;
}

public interface ICommand
    where T : ICommandResult
{
    int Id_User { get; }
}

public interface ICommandResult
{
    bool Success { get; }

    Exception Error { get; }

    ICollection BrokenRules { get; }
}

public interface ICommandHandler
    where TCommand : ICommand
    where TResult : ICommandResult
{
    TResult Execute(TCommand command);
}

public interface ICommandObserver
    where TCommand : ICommand
    where TResult : ICommandResult
{
    void Trigger(TCommand command, TResult result);
}


And here is the CommandBus implementation (using Structuremap as the DI)

public class CommandBus : ICommandBus
{
    private readonly IContainer m_container;

    public CommandBus(IContainer container)
    {
        m_container = container;
    }

    public TResult Publish(TCommand command)
        where TResult : ICommandResult
        where TCommand : ICommand
    {
        using (MiniProfiler.Current.Step("CommandBus.Publish"))
        {
            var handler = m_container.GetInstance>();
            var observers = m_container.GetAllInstances>();

            var result = handler.Execute(command);

            foreach (var observer in observers)
                observer.Trigger(command, result);

            return result;
        }
    }
}


How to use:

```
public class CreateItemCommand: ICommand
{
public string

Solution

This is insanely nit-picky, but this is really just driving me nuts.

TResult Publish(TCommand command)


We read left to right from the return type to the name to the parameters, but you're ordered your generic types from param to result. I think this would be much easier to read as

TResult Publish(TCommand command)


It keeps the declaration closer to its use. Which is, admittedly, trivial in this case, but I think it makes the signature read more like a sentence.

On another note though, I really like that you're filtering the acceptable types. It reminds me that I need to do this more often myself. It's better than just trusting that you (or someone else most likely) knows what kind of types are okay to use generically.

Code Snippets

TResult Publish<TCommand, TResult>(TCommand command)
TResult Publish<TResult, TCommand>(TCommand command)

Context

StackExchange Code Review Q#91693, answer score: 2

Revisions (0)

No revisions yet.