我想使用拦截来在我的应用程序中添加日志记录,而不必使用以下行填充我的代码: “Logger.Log(有什么);”
我知道这被认为是“交叉问题”,这意味着可以使用面向方面编程来很好地处理它。 我认为以下两个选项对我来说效果不佳。 1- Postsharp:不能用于社区版 2- Unity Framework:提供MarshalByRef的接口拦截,虚方法和继承。这些选项都不起作用,因为我无法为项目中的每个类编写新接口。我无法使所有方法都是虚拟的,我无法破坏继承结构并将继承限制为MarshalByRef
我可能会以错误的方式思考问题。在此先感谢您的帮助。
答案 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.
只有最低的性能成本(原始电话+您的代表)。