当命令存储在列表中时,无法使用Autofac解决



如果有下面的代码,实现命令模式。我想在一个列表中存储几个命令,然后从列表中选择它们,解析命令处理程序,最后执行命令。

在实现这一点时,我遇到了一个问题,即从Autofac解析单个命令是有效的,但解析存储在列表中的命令会引发一个异常,告诉我找不到命令处理程序,即使它是与我以前解析命令处理程序相同的命令。

    public static void ShowResolveProblem()
    {
        var action = new DisplayMessageAction("Hello");
        var actionhandler = GetActionHandler(action); // this works well
        var actions = new List<IAction>();
        actions.Add(action);
        actionhandler = GetActionHandler(actions[0]); // this throws exception
    }

这就是的解决方法

    private static IActionHandler<T> GetActionHandler<T>(T action) where T : IAction
    {
        var container = GetActionHandlerContainer();
        return container.Resolve<IActionHandler<T>>();
    }

有人知道怎么做吗?

如果在解析actionHandler时没有具体类型,可以使用typeof(IActionHandler<>).MakeGenericType(action.GetType())获取它。

要在没有T的情况下使用IActionHandler<T>,您必须创建一个新的IActionHandler接口:

class Program
{
    static void Main(string[] args)
    {
        ContainerBuilder builder = new Autofac.ContainerBuilder();
        builder.RegisterAssemblyTypes(typeof(IActionHandler<>).Assembly)
               .AsClosedTypesOf(typeof(IActionHandler<>));
        IContainer container = builder.Build();
        List<IAction> actions = new List<IAction>();
        actions.Add(new DisplayMessageAction("Test1"));
        actions.Add(new DisplayMessageAction("Test2"));
        actions.Add(new BeepMessageAction(200, 200));
        foreach (IAction action in actions)
        {
            Type actionHandlerType = typeof(IActionHandler<>).MakeGenericType(action.GetType()); 
            IActionHandler actionHandler = (IActionHandler)container.Resolve(actionHandlerType);
            actionHandler.Execute(action);
        }
    }
}
public interface IAction { }
public interface IActionHandler
{
    void Execute(IAction action);
}
public interface IActionHandler<T> : IActionHandler
    where T : IAction
{
    void Execute(T IAction);
}
public abstract class ActionHandlerBase<T> : IActionHandler<T>
    where T : IAction
{
    void IActionHandler.Execute(IAction action)
    {
        this.Execute((T)action);
    }
    public abstract void Execute(T IAction);
}
public class DisplayMessageAction : IAction
{
    public DisplayMessageAction(String message)
    {
        this._message = message;
    }
    private readonly String _message;
    public String Message
    {
        get
        {
            return this._message;
        }
    }
}
public class DisplayMessageActionHandler : ActionHandlerBase<DisplayMessageAction>
{
    public override void Execute(DisplayMessageAction action)
    {
        Console.WriteLine(action.Message);
    }
}
public class BeepMessageAction : IAction
{
    public BeepMessageAction(Int32 frequency, Int32 duration)
    {
        this._frequency = frequency;
        this._duration = duration;
    }
    private readonly Int32 _frequency;
    private readonly Int32 _duration;
    public Int32 Frequency
    {
        get
        {
            return this._frequency;
        }
    }
    public Int32 Duration
    {
        get
        {
            return this._duration;
        }
    }
}
public class BeepMessageActionHandler : ActionHandlerBase<BeepMessageAction>
{
    public override void Execute(BeepMessageAction action)
    {
        Console.Beep(action.Frequency, action.Duration);
    }
}

相关内容

  • 没有找到相关文章

最新更新