使用Unity的命令调度程序

时间:2015-10-31 07:14:11

标签: asp.net-mvc unity-container decorator cqrs

我使用Unity作为IoC的命令装饰器模式实现MVC应用程序。

问题:我现在关注的是我注入了多个命令处理程序接口类型的控制器。我到目前为止找到的样本是Ninject和Autofac。

目标:我正在寻找一个命令调度程序,它将根据命令巧妙地决定要解析哪个命令处理程序,这样我就不必处理管理我的控制器的构造函数。

我的命令处理程序界面。

public interface ICommandHandlerAsync<TCommand> 
{
    Task Handle(TCommand command);
}

我的控制器有以下构造函数

public MemberRegistrationController(
        Func<ICommandHandlerAsync<RegisterMemberCommand>> registerMemberCommandHanderFactory,
        Func<ICommandHandlerAsync<UnregisterMemberCommand>> unregisterMemberCommandHanderFactory)
{
...
}

public async void Register(RegisterMemberViewModel vm)
{
    // Map to command using extension
    var cmd = vm.MapToCommand();

    // Run command
    await registerMemberCommandHanderFactory().Handle(cmd);
}

public async void Unregister(UnregisterMemberViewModel vm)
{
    // Map to command using extension
    var cmd = vm.MapToCommand();

    // Run command
    await unregisterMemberCommandHanderFactory().Handle(cmd);
}

我想要的是类似的东西 public MemberRegistrationController(             Func commandDispatcherFactory     {     ...     }

public async void Register(RegisterMemberViewModel vm)
{
    // Map to command using extension
    var cmd = vm.MapToCommand();

    // Run command
    await commandDispatcherFactory().Dispatch(cmd);
}

public async void Unregister(UnregisterMemberViewModel vm)
{
    // Map to command using extension
    var cmd = vm.MapToCommand();

    // Run command
    await commandDispatcherFactory().Dispatch(cmd);
}

由于

1 个答案:

答案 0 :(得分:1)

您可以创建一个命令处理程序工厂,它使用Unity来获取适当的ICommandHandlerAsync<TCommand>的新实例(Unity中的default lifetime是暂时的,这意味着每次你都会获得一个新实例解决类型):

public interface ICommandHandlerFactory
{
    ICommandHandlerAsync<TCommand> GetHandlerFor<TCommand>(TCommand command);
}

public class CommandHandlerFactory: ICommandHandlerFactory
{
    private IUnityContainer container;
    public CommandHandlerFactory(IUnityContainer container)
    {
        this.container = container;
    }

    public ICommandHandlerAsync<TCommand> GetHandlerFor<TCommand>(TCommand command)
    {
        return this.container.Resolve<ICommandHandlerAsync<TCommand>>();
    }
}

然后,您可以在Unity中注册工厂和命令处理程序:

var container = new UnityContainer()
        .RegisterType<ICommandHandlerAsync<RegisterMemberCommand>, RegisterMemberCommandHandler>()
        .RegisterType<ICommandHandlerAsync<UnregisterMemberCommand>, UnregisterMemberCommandHandler>()
        .RegisterType<ICommandHandlerFactory, CommandHandlerFactory>();

您的控制器将在其构造函数中接收工厂。操作方法将使用工厂调度命令:

public MemberRegistrationController(ICommandHandlerFactory commandHandlerFactory)
{
    this.commandHandlerFactory = commandHandlerFactory;
}

public async void Register(RegisterMemberViewModel vm)
{
    // Map to command using extension
    var cmd = vm.MapToCommand();

    // Run command
    await commandHandlerFactory.GetHandlerFor(cmd).Handle(cmd);
}

public async void Unregister(UnregisterMemberViewModel vm)
{
    // Map to command using extension
    var cmd = vm.MapToCommand();

    // Run command
    await commandHandlerFactory.GetHandlerFor(cmd).Handle(cmd);
}

我在this fiddle设置了一个演示。