2

我已经构建了 ac# .net 4.0 库。

所有方法都是公共的和静态的。

我想使用执行以下操作的方面编程库添加方面:

try block
1. call method (if method throws exception)

catch block
2. log the exception and massage the exception

it is a dll (class library project)

如果有一种方法可以在一个类中添加 try/catch 例程而不是一个一个地环绕所有方法,您能否请教?

4

2 回答 2

5

因为您提到过以及其他任何基于static dynamicproxy 的词都不会帮助您,因为它们能够围绕常规方法添加方面。所以你有两个选择:

手写追踪装饰器

添加单独的手写跟踪装饰器,该装饰器将添加所需的功能而无需更改现有代码

  • 好处
    • 简单易写自己
  • 缺点
    • 几乎没有调用上下文。如果您想知道实际调用了哪些方法以及传递了哪些参数等,这对于跟踪很重要。
    • 围绕现有代码的新抽象层。而不是调用你的静态方法,你必须调用装饰器,它会在里面调用你的静态方法

例子

// Decorated calls
TraceDecorator.Aspect(() => StaticLogic.SuccessfulCall());
TraceDecorator.Aspect(() => StaticLogic.ExceptionCall());
TraceDecorator.Aspect(() => StaticLogic.SuccessfulCallWithReturn(42));
TraceDecorator.Aspect(() => StaticLogic.ExceptionCallWithReturn(42));

// Decorator itself
public static class TraceDecorator
{
    public static T Aspect<T>(Func<T> func)
    {
        try
        {
            return func();
        }
        catch(Exception ex)
        {
            LogException(ex);

            return default(T);
        }    
    }

    public static void Aspect(Action func)
    {
        try
        {
            func();
        }
        catch(Exception ex)
        {
            LogException(ex);
        }    
    }

    private static void LogException(Exception ex)
    {
        Console.WriteLine("Traced by TraceDecorator: {0}", ex);
    }
}

此处提供完整示例

PostSharp

看看使用非侵入式跟踪和日志记录

  • 好处
    • 广播您的方面,而无需更改现有代码或自行添加属性,无论您发现什么合适
    • 关注点分离:跟踪/日志记录与您的逻辑分离
    • 还有更多……
  • 缺点
    • 没有什么是免费的。但是有一个功能有限的免费 PostSharp 版本
    • 有时由于后期编译而与其他工具集成
于 2013-01-04T22:02:11.357 回答
0

请参阅开源项目NConcern .NET AOP Framework 。

例子

你的静态类

static public class Calculator
{
    static public int Add(int a, int b)
    {
        return a + b;
    }
}

记录器

static public class Logger
{
    static public void Log(MethodInfo method, object[] arguments, Exception exception)
    {
        Console.WriteLine("{0}({1}) exception = {2}", method.Name, string.Join(", ", arguments), exception.Message);
    }
}

看点:登录异常

public class Logging : IAspect
{
    public IEnumerable<IAdvice> Advise(MethodInfo method)
    {
        yield return Advice.Basic.After.Throwing((instance, arguments, exception) => 
        {
            Logger.Log(method, arguments, exception);
        });
    }
}

Joinpoint : 计算器的方法

var calculatorMethods = new Func<MethodInfo, bool>(method => method.ReflectedType == typeof(Calculator));

激活连接点的日志记录方面

Aspect.Weave<Logging>(calculatorMethods);
于 2016-12-13T05:52:21.520 回答