如果有以下代码,则实现命令模式。我想在列表中存储几个命令,然后从列表中选择它们,解析命令处理程序,最后执行命令。
实现这个时,我遇到了问题,解决单个命令从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>>();
}
有谁知道如何让它运行?
答案 0 :(得分:2)
如果您在解析actionHandler时没有具体类型,则可以使用typeof(IActionHandler<>).MakeGenericType(action.GetType())
获取它。
要在没有IActionHandler<T>
的情况下使用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);
}
}