Comando / modello di gestore e prestazioni

1

Vorrei usare l'approccio command / handler dove registro pochi gestori in global.asax nella mia app MVC e invio comandi a quei gestori da controller MVC.

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");
    }
}

Programma:

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

    // Raise event
    var command = new UpdateCartCommand(532, creditCard);
    var result = CommandProcessor.Send<UpdateCartCommand, CartModel>(command);
  • Sono previsti problemi con la creazione di Istanze di gestori dal contenitore IoC (è lento? E per quanto riguarda le prestazioni?)
  • Quando registri i gestori in IoC con Transient Scope finirò con ogni richiesta con la propria copia di Handler? - (quindi eviterò eventuali problemi di concorrenza)
posta Shane Km 19.08.2016 - 15:42
fonte

1 risposta

1

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

Può essere. Ma come per tutte le prestazioni, l'unico modo per sapere è misurare.

(Inoltre, pensare che il contenitore IoC stia facendo qualcosa di diverso da Activator.CreateInstance per girare su tipi arbitrari è un po 'sciocco)

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)

In generale, sì. Ma i tuoi gestori dovrebbero essere apolidi, il che significa che l'ambito transitorio non ti sta guadagnando nulla di concorrente (e lo scope transitorio non è di per sé un proiettile d'argento per problemi di concorrenza).

    
risposta data 19.08.2016 - 15:56
fonte

Leggi altre domande sui tag