如何将AOP用于静态方法

本文关键字:用于 静态方法 AOP | 更新日期: 2023-09-27 17:50:39

我已经构建了一个c# .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例程,而不是一个接一个地包装所有方法,您可以建议吗?

如何将AOP用于静态方法

因为您已经提到了单词static,无论是ninject还是castle-windsor还是其他基于castle-dynamicproxy的东西都不能帮助您,因为它们能够在常规方法周围添加方面。所以你有两个选择:

手写描摹装饰

添加单独的手写跟踪装饰器,可以在不改变现有代码的情况下添加所需的功能

  • 的好处
    • 简单容易自己写
  • 缺点
    • 几乎没有调用上下文。这对于跟踪很重要,如果你想知道实际调用了什么方法,传递了什么参数等等。
    • 围绕现有代码的新抽象层。而不是调用你的静态方法,你必须调用Decorator,它将在
    • 内部调用你的静态方法

// 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 h1> 看非侵入性追踪&使用postsharp 进行日志记录
  • 的好处
    • 广播你的方面,而不改变现有的代码或自己添加属性,无论你发现合适的
    • 关注分离:跟踪/日志记录与您的逻辑分离
    • 和更多…
  • 缺点
      没有什么是免费的。但是有一个免费的PostSharp版本,功能有限
  • 由于后期编译,有时会与其他工具集成

参见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);
    }
}

Aspect: log on exception

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: methods of Calculator

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

激活连接点

的日志记录方面
Aspect.Weave<Logging>(calculatorMethods);