【问题标题】:AOP (aspect oriented programming) and logging. Is it really functional?AOP(面向方面​​编程)和日志记录。它真的有功能吗?
【发布时间】:2013-11-05 08:49:47
【问题描述】:

我们正在尝试使用 AOP(顺便说一下 PostSharp,但这个问题涉及任何 AOP 框架)在我们的应用程序中实现日志记录。

我们面临的问题是我们得到的信息是这样的:

输入带参数的方法XXX:

  • 参数内容如果是值类型。
  • ToString() 中的任何内容都会覆盖(如果已完成)。
  • 类名,如果 ToString() 没有被覆盖。

此信息不是很有用,因为通常我们得到的是第三种情况。我们也在创造大量无用的信息。

如果您使用 AOP 登录任何产品,您是如何解决这个问题的?

提前致谢。

【问题讨论】:

标签: c# .net logging aop


【解决方案1】:

几种方法:

  • 在要记录的类型上放置一个通用接口。 (例如 ILoggable)。实现该接口将使您的方面能够准确记录您想要的内容。缺点是您必须为可能记录的每个对象实现/维护 ILoggable。

  • 使用反射(这是我在我的博客上audit example 所做的。它使用MVC ActionFilter,但原理相同)。博文中详细说明了权衡取舍,但基本上它是使用反射和性能问题的复杂性,具体取决于您记录的数量和频率。

  • 使用序列化。给定一个对象,将其序列化为 Json 或 XML 或其他任何内容,并记录该字符串。根据您对日志的处理方式,这可能从完美到毫无价值,并且取决于序列化的工作方式和对象的复杂程度,这也可能是一个性能问题。

【讨论】:

  • 谢谢。这些都是好点。最后我们放弃了 AOP 日志的使用,因为我们没有找到完全替代标准日志的方法,我们认为将两个日志系统合二为一是没有意义的。 Anway 以后我会考虑前两点。谢谢!
【解决方案2】:

我正在开发一种新型 AOP 框架,以应对现有 AOP 框架缺失的特性。你可以在这里找到我的开源项目:NConcern .NET AOP Framework

与其他人的区别之一是允许您使用 System.Linq.Expression 开发您的建议,以避免基于类型的装箱/拆箱、反射和哈希跳转。对于初学者来说,使用 Expression 进行开发有点困难,但对于高级开发人员来说却很容易。

一个简单的记录示例(进入控制台)而不重写您的业务、反射和装箱。

企业:计算器

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

您的日志记录方面由 linq 表达式实现,用于描述 Advice 必须如何工作。

public class Logging : IAspect
{
    //this is not an advice, this method is called to produce advices
    public IEnumerable<IAdvice> Advise(MethodInfo method)
    {
        //generic presentation method
        var presentation = typeof(Presentation). GetMethod("Of");

        //example log on exception
        //instance, arguments and exception are Expressions
        yield return Advice.Linq.After.Throwing((instance, arguments, exception) =>
        {
            Expression.Call
            (
                typeof(Console).GetMethod("WriteLine",...),
                Expression.Call
                (
                    typeof(string).GetMethod("Concat", new Type[] { typeof(string[]) }),
                    Expression.NewArrayInit(typeof(string), arguments.Select(argument => argument.Type == typeof(string) ? argument : ...).ToArray())
                )
            )
        }
    }
}

【讨论】:

  • 我明白了,无论如何我的抱怨与性能无关,而是与生成数据的有用性有关。
  • 我明白了,您只需要为日志记录实现一种外部序列化(例如 JSON),以避免记录类名。这个问题更多地与日志记录过程有关,而不是 AOP。
  • 同意,这是一个复杂的问题,因为 AOP 不允许您区分正在记录的内容。
  • 在我的示例中,我使用特定的 Expression 实现来通知方法,在通知创建上下文中,您可以使用反射来获取有关目标方法的信息(自定义属性、参数、声明类型、反射类型。 ..) 以提供专门的建议。如果提供元开发工作,您可以选择要记录的内容(使用通用方式)。您可以像硬编码一样做好日志。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-09-03
  • 2011-06-27
  • 1970-01-01
  • 2011-12-15
  • 2011-04-07
  • 2011-07-30
  • 2011-08-12
相关资源
最近更新 更多