这是张贴在Caliburn.Micro 讨论 http://caliburnmicro.codeplex.com/Thread/View.aspx?ThreadId=244394还。我真的在寻找有关最佳解决方法的建议和意见。
假设我有以下操作
public IEnumerable<IResult> SaveStation()
{
yield return Busy.MakeBusy();
yield return new StationSave(_station);
yield return Busy.MakeNotBusy();
yield return Show.Tab<StationBrowseViewModel>();
}
StationSave 是一个围绕简单 (WCF) 服务调用的 IResult 包装器。该服务使用FaultContract/FaultException 来处理失败。
在出现故障的情况下,需要通知用户,并且FaultContract 将包含一些有关出现问题的有用信息。目前,Save 结果捕获了异常并将其插入到 Completed 事件的 ResultCompletionEventArgs 中。通过这样做,管道创建的 SequentialResult 将被取消(由于错误),从而使屏幕处于忙碌状态。
我真正想要的是从错误中恢复(删除繁忙状态)并通知用户(我有几个 IResult 实现用于不同样式的通知,我想使用)详细信息的最佳方法的想法过错合同中规定。通过附加到虚拟机中的 Completed 事件,我可以获得错误,但此时我不再处于操作管道的上下文中,因此我想要使用的任何 IResults(MakeNotBusy 和我的显示通知实现)我必须手动执行(我必须新建我自己的 ActionExecutionContext,但我不想这样做)。
我看过 Marco Amendola 的 Caliburn.Micro 救援过滤器here http://marcoamendola.wordpress.com/2010/08/10/a-caliburn-micro-recipe-filters/,但我再次无法从 Rescue 方法传回 IResults。
我错过了一些明显的事情吗?其他人如何处理这种情况?
Both 罗布·艾森伯格 http://devlicio.us/blogs/rob_eisenberg/ and 马可·阿门多拉 http://marcoamendola.wordpress.com/中提供了可能的解决方案CodePlex 论坛 http://caliburnmicro.codeplex.com/Thread/View.aspx?ThreadId=244394.
我选择了Marco的RescueAttribute
从他的过滤器的实现 http://marcoamendola.wordpress.com/2010/08/10/a-caliburn-micro-recipe-filters/并稍微修改它以允许进一步执行IResult
从救援方法来看。这是所需的更改RescueAttribute.HandleException
protected override bool HandleException(ActionExecutionContext context,
Exception ex)
{
var method = context.Target
.GetType()
.GetMethod(MethodName, new[] { typeof(Exception) });
if (method == null) return false;
try
{
var result = method.Invoke(context.Target, new object[] { ex });
if (result is bool)
return (bool) result;
if (result is IResult)
result = new[] { result as IResult };
if (result is IEnumerable<IResult>)
Coroutine.Execute(((IEnumerable<IResult>) result).GetEnumerator(), context);
else if (result is IEnumerator<IResult>)
Coroutine.Execute(((IEnumerator<IResult>) result), context);
return true;
}
catch
{
return false;
}
}
这允许在我的虚拟机中执行以下操作:
public IEnumerable<IResult> Rescue(Exception ex)
{
yield return Busy.MakeNotBusy();
// in practice pass exception details through to notification
yield return new NotificationPopup("Save station failed");
}
[Rescue]
public IEnumerable<IResult> SaveStation()
{
yield return Busy.MakeBusy();
yield return new StationSave(_station);
yield return Busy.MakeNotBusy();
yield return Show.Tab<StationBrowseViewModel>();
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)