【问题标题】:C# How do I use AOP for static methods?C# 如何将 AOP 用于静态方法?
【发布时间】:2016-12-13 13:52:21
【问题描述】:

我已经构建了一个 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 例程,而不是一个一个地包裹所有方法,您能否提出建议?

【问题讨论】:

  • 我还没有实现任何东西,但我查看了一些库。我简要地查看了 ninject、castle windsor 和 spring.net,但我不确定是否可以为类库中的静态方法做我想做的事情?
  • “所有的方法都是公共的和静态的”——嗅,嗅。代码味道...
  • 我不明白为什么它被关闭了。对我来说似乎是一个合法的问题。
  • @DStanley 本身可能只是一个功能样式库。例外计划似乎更奇怪。
  • 它将由 managedXll 使用,这要求所有方法都是公共静态的。有一个 catch 块的原因是因为我必须接受异常并通过 managedxll 将其作为可调整大小的数组发送回,还必须通过对另一个应用程序进行 api 调用来记录异常,而不是为每个方法重复它,我想在 AOP 中介绍它

标签: c# .net aop


【解决方案1】:

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

手写追踪装饰器

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

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

示例

// 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);
    }
}

提供完整示例here

PostSharp

看看Non-Invasive Tracing & Logging

  • 优点
    • 广播您的方面,无需更改现有代码或自行添加属性,只要您认为合适即可
    • 关注点分离:跟踪/日志记录与您的逻辑分离
    • 还有更多……
  • 缺点
    • 没有什么是免费的。但是有一个免费的 PostSharp 版本,功能有限
    • 有时会因为后期编译而与其他工具集成

【讨论】:

    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-11-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-08-30
      • 1970-01-01
      相关资源
      最近更新 更多