如何使用简单的面向方面的概念来处理没有postharp的异常处理?

时间:2016-10-27 06:09:47

标签: c# oop design-patterns aop postsharp

我想使用AOP来处理控制台应用程序中的错误异常。 (这不是MVC我使用属性花瓶编程来处理mvc中的错误,但这是控制台应用程序)我的代码如下:(如果发生错误,它应该抛出我的属性边代码错误)

 [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
public class HandleError : Attribute
{
     public HandleError(string description)
    {
        try
        {
            this.Description = description;
        }
        catch (Exception)
        {

            throw;
        }

    }
    public string Description { get; set; }


}

这将从我的方法调用:

   [HandleError("Error occurs here")]
    public static void MyMethod(string data)
    {
        throw new Exception();

实际上;我想使用AOP来处理我的方法中的异常。如果发生错误,我必须调用属性。但是怎么样? (请不要提供postharp,它需要钱。但我也对开源也开放)顺便说一下;为什么这不容易,我不明白。

1 个答案:

答案 0 :(得分:4)

基本上,PostSharp所做的是在编译时将代码编织到程序集中,该编译时在使用属性标记的方法之前和之后运行。从性能的角度来看,这是非常好的,因为没有使用在运行时动态创建的代码。

其他一些AOP框架(或IoC容器)提供了生成动态代理的选项,这些代理包含在运行时拦截对方法的调用的代码。

要么使用其中一个框架(寻找IoC和拦截),要么自己实现类似的功能。基本上,您需要做的是将要拦截的代码移动到类中,并将方法标记为virtual。在运行时,您使用动态创建的类来装饰类的实例,该类继承自您的类并重写方法,以便在调用方法之前和之后运行其他代码。

但是,可能有一种更简单的方法可以满足控制台应用程序的需求。您还可以创建一些辅助函数,而不是使用属性标记方法,这些函数包含您希望在方法之前和之后运行的代码:

void Main()
{
    int value = GetValue(123);
    DoSomething(value);
}

void DoSomething(int myParam)
{
    RunAndLogError(() => {
        // Place code here
        Console.WriteLine(myParam);
        });
}

int GetValue(int myParam)
{
    return RunAndLogError(() => {
        // Place code here
        return myParam * 2;});
}

void RunAndLogError(Action act)
{
    try
    {
        act();
    }
    catch(Exception ex)
    {
        // Log error
        throw;
    }
}

T RunAndLogError<T>(Func<T> fct)
{
    try
    {
        return fct();
    }
    catch(Exception ex)
    {
        // Log error
        throw;
    }
}

如您所见,RunAndLogError有两个重载,一个用于void方法,另一个用于返回值的方法。

另一种选择是为此目的使用全局异常处理程序;有关详细信息,请参阅此答案:.NET Global exception handler in console application