在我正在构建的系统中,我使用命令模式执行所有可能的操作。我选择了CommandMessage和CommandHandler方法,将逻辑从数据中分离出来。 现在工作正常,但我遇到了问题 - 验证。在执行前验证命令
我该如何验证命令是否可以执行?
现在我每个命令都有一个CanExecute(ICommandExecutionContext context)
,使它负责确定它是否可以执行。然后在每个命令中查找一个ICommandExecutionContext
,查看它是否属于正确的上下文类型,之后如果信息使该命令在该上下文中可执行。
所有内容都包含在ICommandService
中,可以根据其名称,上下文和消息验证和执行命令。除此之外,它还发布关于命令执行的事件,并执行权限检查。
该问题源于UI(ASP.NET MVC 3应用程序)。我只想在每个视图中显示有效的命令,但我没有想出一个我真正喜欢的解决方案。目前我的控制器询问命令服务,一个命令是否能够执行,给出一个具体的情境,像这样:
var executionContext = new SystemCommandExecutionContext("SignInCommand", CurrentPrincial);
var canExecute = _commandService.CanExecute(executionContext);
/* Handle the result to enable or disable the action link */
对于其他类型的命令,即在具体的领域对象的作品,我用同样的命令服务方法,但一个不同的上下文,我通过域对象ID,像这样:
[HttpPost, Authorize, ValidateAntiForgeryToken /* etc. */]
public ActionResult Delete(Guid id)
{
/* Note the additional object id in the context */
var executionContext = new EntityCommandExecutionContext("DeletePersonCommand", CurrentPrincipal, id);
var canExecute = _commandService.CanExecute(executionContext);
if(canExecute)
{
var message = new DeletePersonCommandMessage(id);
var isValid = _commandService.IsValid(executionContext, message);
if(isValid)
{
var result = _commandService.Execute(executionContext, message);
/* More logic here... Not very DRY :(*/
}
}
}
我猜上述现在好了,虽然不是非常干燥。 但我想完成的是根据CanExecute的结果禁用操作链接。
我该怎么做?
我决定在每个视图上“硬编码”所有的命令链接,所以我不必传递命令集合等等 - 这个路径太困难了(除非有人有一个聪明的想法;)
我目前的堆栈由NHibernate,Castle Windsor,ASP.NET MVC 3,AutoMapper组成。
这与我现在的情况差不多。我不确定你的意思是关于我的命令模式实现。你能详细说明一下吗?我相信(也许我不清楚),你忘了命令操作域对象?我不确定我如何能够向验证服务提供域信息的上下文? – Siewers 2011-12-30 09:59:10