我的DAL不处理异常,它将传播到将处理异常的演示者类中的调用方法。
我正在使用一个名为ExecutAction(Action action)
的处理程序,所以我在一个地方捕获异常,而不是在每个方法中重复。
目前,我没有记录错误。只需提醒用户注意某个操作,并尽可能让系统保持活动状态。
向用户显示消息时,Presenters将使用名为MessagingService
的静态类。 (ShowErrorMessage()
)。这样我就可以在一个地方定制所有按摩盒。
private void Search()
{
ExecutAction(() =>
{
var info = _DataService.GetByACNo(_model.AccountNumber);
if (info != null)
{
_Model = info ;
this.SetViewPropertiesFromModel(_Model, _View);
}
else
{
MessageBox.Show ("Bank account not found");
}
});
}
private void ExecutAction(Action action)
{
try
{
action();
}
catch (NullReferenceException e) { MessagingService.ShowErrorMessage(e.Message); }
catch (System.Data.SqlTypes.SqlTypeException e) { MessagingService.ShowErrorMessage(e.Message); }
catch (System.Data.SqlClient.SqlException e) { MessagingService.ShowErrorMessage(e.Message); }
}
}
我应该为此包含一般异常处理程序,以便能够处理任何不可预见的异常吗?
你还能告诉我一个更好的方法来处理显示消息而不是使用静态吗?
在每个方法调用(ExecutAction(() =>
)中使用lambda语句会降低代码的可读性吗?
当显示用户消息时如何首先显示“检查服务器连接”等自定义消息,然后如果用户想要更多信息(如StackTrace /技术细节),他/她可以按下{{1}之类的按钮在MessageBox对话框中?
答案 0 :(得分:2)
我认为你的方法对你的工作来说已经足够了。以ExecuteAction
包装逻辑对我来说是一种可接受的方式。作为另一种选择,我可能会在实践中使用AOP进行集中式异常处理。
此外,我可能会使用从依赖注入容器中解析的MessagingService
而不是静态容器。
关于如何显示错误,这完全取决于您的业务目的。例如,您可以简单地记录错误并告诉用户“出错了”,或者向他们展示完整的堆栈跟踪,包括环境信息,这样他们就可以简单地复制&粘贴在电子邮件中。
答案 1 :(得分:2)
我同意jeffrey关于尝试将IoC用于您的留言服务。您可以定义一个抽象基本presenter类,它依赖于您的消息服务的接口。基类将负责处理委托执行+异常日志记录。
public interface IMessageService
{
void ShowErrorMessage(Exception e);
}
public abstract class PresenterBase
{
private readonly IMessageService _messageService;
public PresenterBase(IMessageService messageService)
{
this._messageService = messageService;
}
protected void ExecuteAction(Action action)
{
try
{
action();
}
catch (Exception e) { this._messageService.ShowErrorMessage(e); }
}
}
public class SearchPresenter: PresenterBase
{
public SearchPresenter(IMessageService messageService)
: base(messageService)
{
}
public void Search()
{
this.ExecuteAction(() =>
{
//perform search action
});
}
}
关于捕获所有记录的问题。除非你为特定类型的异常做一些特殊的事情,否则我建议你处理所有相同的事情。我提供的示例将异常传递给消息服务,以便您的消息服务可以处理格式细节。
如果您尚未合并任何类型的IoC容器,则始终可以先使用接口注入,然后从子类构造函数中显式传递实例。
public class SearchPresenter: PresenterBase
{
public SearchPresenter()
: base(new SomeMessageService())
{
}
...
}
这至少可以消除静态依赖关系,如果你引入了一个IoC容器,那么以后就不用太多了。