简体   繁体   English

C#类范围内的异常处理

[英]c# class-wide exception handling

Is it possible to catch exceptions in a single place in ac# class file? 是否可以在ac#类文件中的单个位置捕获异常?

I'm coding some unit tests in NUnit to test for a WCF Web-Service, and on all methods/tests want to trap a "EndpointNotFoundException" without having to code this for each test. 我正在NUnit中编码一些单元测试以测试WCF Web服务,并且在所有方法/测试上都希望捕获“ EndpointNotFoundException”,而不必为每个测试编码。

edit 编辑

I guess i wanted to create a descriptive error in this case without having to put an additional catch block in each method, as i do indeed want the test to fail. 我想我想在这种情况下创建一个描述性错误,而不必在每个方法中都放置一个额外的catch块,因为我确实确实希望测试失败。

As i've done something similar to this in WCF with the FaultException i was interested to know if it was possible in general with C# classes 因为我用FaultException在WCF中做了类似的事情,所以我很想知道C#类是否有可能

But the bottom line is that if it fails, it fails! 但最重要的是,如果失败,它将失败! thanks to @TrueWill for stating the obvious ;) and to @Abhijeet Patel for making me think more about how i structure my unit tests 感谢@TrueWill陈述明显的;)并感谢@Abhijeet Patel让我更多地思考我如何构建单元测试

(oh, and apologies for answering my own question ;) (哦,很抱歉回答我自己的问题;)

In general , no - you can only catch locally. 一般而言 ,否-您只能在本地捕鱼。 There are isolated exceptions occasions when you can do this - ASP.NET MVC controllers and WCF services being two examples that leap to mind where the error handling can easily (or easily enough ) separated. 在某些情况下,您可以单独执行此操作-ASP.NET MVC控制器和WCF 服务是两个可以让您轻松(或足够容易)分离错误处理的示例。

But in your case - don't you just want to add [ExpectedException(...)] to the affected tests? 但是就您而言-您是否只想向受影响的测试添加[ExpectedException(...)]

Perhaps a better approach would be to look into injecting the exception handling code with AOP (postsharp) or policy injection? 也许更好的方法是考虑使用AOP(后锐化)或策略注入来注入异常处理代码?

AFAIK, what you are trying to do is not possible. AFAIK,您无法执行的操作。 You can look into Application.ThreadException and AppDomain.CurrentDomain.UnhandledException for centralized exception handling. 您可以查看Application.ThreadException和AppDomain.CurrentDomain.UnhandledException以进行集中式异常处理。

You can use AOP to achieve this. 您可以使用AOP实现此目的。 The idea is, as you request, to attach some behaviour (exception handling in this case) to all methods in the class. 根据您的要求,该想法是将某些行为(在这种情况下为异常处理)附加到类中的所有方法。

For example, using PostSharp , you can define the following "exception handler": 例如,使用PostSharp ,您可以定义以下“异常处理程序”:

[Serializable]
class EndpointNotFoundExceptionHandlerAspect : OnExceptionAspect
{
    public override void OnException(MethodExecutionEventArgs eventArgs)
    {
        if (eventArgs.Exception is EndpointNotFoundException)
            eventArgs.FlowBehavior = FlowBehavior.Continue; // continue without throwing an exception
        else
            base.OnException(eventArgs);
    }
}

Then add the EndpointNotFoundExceptionHandlerAspect to your class definition. 然后将EndpointNotFoundExceptionHandlerAspect添加到您的类定义。 Then every time the EndpointNotFoundException is thrown, it will be "handled". 然后,每次抛出EndpointNotFoundException ,都会对其进行“处理”。

Note: I make no claims that this is a good idea. 注意:我不主张这是个好主意。 This is merely an example of how it can be achieved. 这仅仅是如何实现它的一个例子。

可以进行面向方面的编程来处理诸如EndpointNotFoundException ..之类的单一类型的异常,并且可以使用该异常将其记录在某处。

An approach I've taken to this sort of problem is by providing an InvokeAction method which allows you to manage your exception handling in a relatively unified way. 我针对此类问题采取的一种方法是提供InvokeAction方法,该方法允许您以相对统一的方式管理异常处理。 This does rely on each of your methods having a similar signature however, naturally you can provide more signatures to cover these other actions: 这确实依赖于您的每个方法都具有相似的签名,但是,自然地,您可以提供更多的签名来覆盖这些其他操作:

private void InvokeAction (Action<TData> action, data)
{
    try
    {
        action(data);
    }
    catch (EndpointNotFoundException enfe)
    {
        .... unified handling here
    }
    catch (OtherExceptionType oet)
    {
    }
}

Using this approach you can then make a call to your service methods which will all have the same try catch block invocation. 然后,您可以使用这种方法调用您的服务方法,这些方法都将具有相同的try catch块调用。

eg InvokeAction(AddUser, userData); 例如InvokeAction(AddUser, userData);

eg InvokeAction(UpdateUser, userData); 例如InvokeAction(UpdateUser, userData);

You'll have to create a logging mechanism (or use a third party implementation like log4net) and insert catch blocks everywhere, where the exceptions are logged. 您将必须创建一个日志记录机制(或使用第三方实现,例如log4net),并在记录异常的任何地方插入catch块。 In other words, no. 换句话说,没有。

As Marc already pointed out, using an [ExpectedException] on the unit test seems to be the most logical way to go especially for unit tests, where you want to focus on a unit of functionality. 正如Marc所指出的那样,在单元测试中使用[ExpectedException]似乎是最合乎逻辑的方法,特别是对于要重点关注功能单元的单元测试。 if you are doing a lot of try...catch style processing and conditional checking then your unit test isn't really a unit test 如果您要进行很多尝试...捕获样式处理和条件检查,那么您的单元测试并不是真正的单元测试

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM