使用 Unity 的命令调度程序

Command Dispatcher using Unity

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

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

Objective:我希望实现一个命令调度程序,它将根据命令巧妙地决定要解析哪个命令处理程序,这样我就不会处理管理我的控制器的构造函数。

我有我的命令处理程序界面。

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会员注册控制器( 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);
}

谢谢

你可以创建一个command handler factory,它使用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中设置了一个演示。