.NET - 没有继承或Postsharp的拦截对象

时间:2015-03-15 11:27:56

标签: c# .net postsharp aop

我想使用拦截来在我的应用程序中添加日志记录,而不必使用以下行填充我的代码: “Logger.Log(有什么);”

我知道这被认为是“交叉问题”,这意味着可以使用面向方面编程来很好地处理它。 我认为以下两个选项对我来说效果不佳。 1- Postsharp:不能用于社区版 2- Unity Framework:提供MarshalByRef的接口拦截,虚方法和继承。这些选项都不起作用,因为我无法为项目中的每个类编写新接口。我无法使所有方法都是虚拟的,我无法破坏继承结构并将继承限制为MarshalByRef

我可能会以错误的方式思考问题。在此先感谢您的帮助。

2 个答案:

答案 0 :(得分:2)

看一下Real Proxy课程。您可以使用它来非常轻松地实现装饰器模式:

public class LoggingDecorator<T> : RealProxy
{
    private readonly T _decorated;

    public LoggingDecorator(T decorated)
        : base(typeof(T))
    {
        _decorated = decorated;
    }

    public override IMessage Invoke(IMessage msg)
    {
         // Add logging action here

         var methodCall = msg as IMethodCallMessage;
         var methodInfo = methodCall.MethodBase as MethodInfo;

         // Invoke actual method
         var result = methodInfo.Invoke(_decorated, methodCall.InArgs);

         return new ReturnMessage(result, null, 0, methodCall.LogicalCallContext, methodCall);
    }
}

如果您正在使用IoC,您应该能够使用装饰器注册组件。

答案 1 :(得分:1)

尝试NConcern

这是一个简单的AOP框架(我积极参与其中),允许您在运行时应用横切关注,而无需更改构建系统,继承强制和工厂/代理模式。它可以处理非虚方法,因为它使用代码注入。

记录方面

//define aspect to describe how handle logging
public class Logging : Aspect
{
    //describe how to log
    override protected IEnumerable<Advice<T>> Advise(MethodInfo method)
    {
        //after method call, log method name.
        yield return Advice<T>.Basic.After(() => Logger.Log(method.Name));
    }
}

示例类

public sealed class SampleClass
{
    public void SampleMethod()
    {
    }
}

这里有如何使用

var logging = new Logging();

//inject logging aspect to SampleClass
logging.Manage<SampleClass>();

//now when SampleMethod is called, it is logged.

只有最低的性能成本(原始电话+您的代表)。