我想改变使用WPF命令处理异常的方式
视图中的简单命令:
<!-- language: lang-html -->
<dxr:RibbonPageGroup x:Uid="dxr:RibbonPageGroup_1" Caption="Edit">
<dxb:BarButtonItem x:Uid="dxb:BarButtonItem_1" Content="Save" Command="{Binding SaveCommand}" LargeGlyph="{dx:DXImage Image=Save_32x32.png}" Glyph="{dx:DXImage Image=Save_16x16.png}"/>
</dxr:RibbonPageGroup>
<!-->
视图模型中的简单命令方法如下所示:
<!-- language: c# -->
[Command ="SaveCommand"]
public virtual void Save()
{
try
{
//do stuff
throw new InvalidOperationException("This is simple exception");
}
catch(Exception ex)
{
IConfigurationSource config = ConfigurationSourceFactory.Create();
ExceptionPolicyFactory factory = new ExceptionPolicyFactory(config);
Logger.SetLogWriter(new LogWriterFactory().Create(), false);
ExceptionManager exceptionManager = factory.CreateManager();
exceptionManager.HandleException(ex, "Policy");
}
}
<!-->
每当我添加新命令时,我需要复制并粘贴相同的代码,并使源代码减少并且难看。
所以我想使用
将异常处理的方式更改为更优雅的方式<!-- language: c# -->
exceptionManager.Process(() => { Save(); }, "Policy");
<!-->
但问题是这不会起作用:
<!-- language: c# -->
[Command ="SaveCommand"]
public virtual void Save()
{
IConfigurationSource config = ConfigurationSourceFactory.Create();
ExceptionPolicyFactory factory = new ExceptionPolicyFactory(config);
Logger.SetLogWriter(new LogWriterFactory().Create(), false);
ExceptionManager exceptionManager = factory.CreateManager();
exceptionManager.Process(() => { Save(); }, "Policy");
}
<!-->
因为我已经在Save()方法范围内了 - 我希望你知道我的意思。
最佳解决方案是使用类似于PostSharp的机制进行异常处理 - 使用反射并使用属性装饰Save()方法
<!-- language: c# -->
[FormatedException(Policy = "Policy")]
public virtual void Save()
{
}
<!-->
你们觉得怎么样? 我想知道你的意见,也许你找到更好的解决方案。也许是有办法在视图模型中执行它之前包装命令。
答案 0 :(得分:0)
您可以稍微更改语法,将所需的所有语句放在通用异常处理程序中运行:
[Command ="SaveCommand"]
public virtual void Save()
{
exceptionManager.Process(() =>
{
IConfigurationSource config = ConfigurationSourceFactory.Create();
ExceptionPolicyFactory factory = new ExceptionPolicyFactory(config);
Logger.SetLogWriter(new LogWriterFactory().Create(), false);
ExceptionManager exceptionManager = factory.CreateManager();
},
"Policy");
}
或者,您可以将其分解为两个函数
[Command ="SaveCommand"]
public virtual void TrySave()
{
exceptionManager.Process(() =>
{
Save();
},
"Policy");
}
public virtual void Save()
{
IConfigurationSource config = ConfigurationSourceFactory.Create();
ExceptionPolicyFactory factory = new ExceptionPolicyFactory(config);
Logger.SetLogWriter(new LogWriterFactory().Create(), false);
ExceptionManager exceptionManager = factory.CreateManager();
}