1

I would like to use command / handler approach where I register few handlers in global.asax in my MVC app and send commands from MVC controllers to those handlers.

public class CommandProcessor
{
    private static readonly ConcurrentDictionary<Type, Type> ListOfHandlers = new ConcurrentDictionary<Type, Type>();

    public static void RegisterHandler<TCommand, TCommandHandler>()
        where TCommand : Command
    {
        ListOfHandlers.TryAdd(typeof (TCommand), typeof (TCommandHandler));
    }

    public static TViewModel Send<TCommand, TViewModel>(TCommand command)
        where TCommand : Command
        where TViewModel : IViewModelBase, new()
    {
        if (!ListOfHandlers.ContainsKey(typeof (TCommand)))
            return new TViewModel();

        var typeOfHandler = ListOfHandlers[typeof (TCommand)];

        // Slow but I can use IoC
        //var instance = (ICommandHandler<TCommand, TViewModel>)Activator.CreateInstance(typeOfHandler);

        // Get from container
        var instance = (ICommandHandler<TCommand, TViewModel>)IoContainer.container.TryGet<object>(typeOfHandler.Name);

        return instance.Handle(command);
    }
}

public class UpdateCartHandler : ICommandHandler<UpdateCartCommand, CartModel>
{
    private readonly ICreditCard creditCard;

    // IoC Sample
    public UpdateQuantityHandler(ICreditCard creditCart)
    {
        creditCard = creditCart;
    }

    public CartModel Handle(UpdateQuantityCommand command)
    {
        // perform processing
        ...
    }
}


public static class IoContainer
{
    public static IKernel container;
    static IoContainer()
    {
        container = new StandardKernel(new Registry());
    }
}

// Simple IoC Registry
public class Registry : NinjectModule
{
    public override void Load()
    {
        Kernel.Bind<object>()
            .To<UpdateCartHandler>()
            .InTransientScope()
            .Named("UpdateCartHandler");
    }
}

Program:

    // Register - in Global.asax
    CommandProcessor.RegisterHandler<UpdateCartCommand, UpdateCartHandler>();

    // Raise event
    var command = new UpdateCartCommand(532, creditCard);
    var result = CommandProcessor.Send<UpdateCartCommand, CartModel>(command);
  • Do you foresee any issues with creating Instances of handlers from IoC container (is it slow? what about performance?)
  • When registering handlers in IoC with Transient Scope will I end up with each request having it's own copy of Handler? - (therefore I will avoid any concurrency issues)
1

Do you foresee any issues with creating Instances of handlers from IoC container (is it slow? what about performance?)

It can be. But as with all things performance, the only way to know is to measure.

(Also, thinking the IoC container is doing anything other than Activator.CreateInstance for spinning up arbitrary types is a bit silly)

When registering handlers in IoC with Transient Scope will I end up with each request having it's own copy of Handler? - (therefore I will avoid any concurrency issues)

Generally, yes. But your handlers should be stateless, meaning the transient scope isn't gaining you anything concurrency wise (and transient scope isn't itself a silver bullet for concurrency issues).

  • But my handlers may end up having 2-5 dependencies...therefore I would like to have the container resolve these instances for me. Wouldn't it be the right approach then? – Shane Km Aug 19 '16 at 13:57
  • "Generally, yes. But your handlers should be stateless, meaning the transient scope isn't gaining you anything concurrency wise (and transient scope isn't itself a silver bullet for concurrency issues)." - of course I would have to make sure concurrency issues don't creep in once "processing" in the handler takes place – Shane Km Aug 19 '16 at 14:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.