C# .NET-拦截不带继承或Postsharp的对象
我希望使用拦截在我的应用程序中添加日志记录,而不必在代码中填充以下行: “Logger.Log(某物);” 我知道这被认为是一个“交叉关注点”,这意味着可以使用面向方面的编程很好地处理它。 我考虑了以下两个不适合我的选择。 1-Postsharp:不能在社区版上使用 2-Unity框架:提供接口拦截、虚拟方法和MarshalByRef继承。这些选项都不起作用,因为我无法为项目中的每个类编写新接口。我不能使所有方法都是虚拟的,也不能破坏继承结构并将继承限制为MarshalByRef 我可能想错了这个问题。提前感谢您的帮助。请看一下课程。您可以很容易地使用它来实现decorator模式:C# .NET-拦截不带继承或Postsharp的对象,c#,.net,postsharp,aop,C#,.net,Postsharp,Aop,我希望使用拦截在我的应用程序中添加日志记录,而不必在代码中填充以下行: “Logger.Log(某物);” 我知道这被认为是一个“交叉关注点”,这意味着可以使用面向方面的编程很好地处理它。 我考虑了以下两个不适合我的选择。 1-Postsharp:不能在社区版上使用 2-Unity框架:提供接口拦截、虚拟方法和MarshalByRef继承。这些选项都不起作用,因为我无法为项目中的每个类编写新接口。我不能使所有方法都是虚拟的,也不能破坏继承结构并将继承限制为MarshalByRef 我可能想错了这
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);
}
}
公共类LoggingDecorator:RealProxy
{
私人只读T_;
公共伐木装饰工(T装饰)
:基础(类型(T))
{
_装饰的=装饰的;
}
公共覆盖IMessage调用(IMessage msg)
{
//在此处添加日志记录操作
var methodCall=msg作为IMethodCallMessage;
var methodInfo=methodCall.MethodBase作为methodInfo;
//调用实际方法
var result=methodInfo.Invoke(_,methodCall.InArgs);
返回新的ReturnMessage(结果,null,0,methodCall.LogicalCallContext,methodCall);
}
}
如果您使用的是IoC,您应该能够向decorator注册组件。试试看
它是一个简单的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));
}
}
这里如何使用
var logging = new Logging();
//inject logging aspect to SampleClass
logging.Manage<SampleClass>();
//now when SampleMethod is called, it is logged.
var logging=newlogging();
//将日志方面注入SampleClass
logging.Manage();
//现在,当调用SampleMethod时,它将被记录。
只有最低的性能成本(原始通话+您的代理人)。如果您是这个意思,PostSharp可以与VS Community Edition一起使用。请提供无法使用PostSharp的详细信息。为什么需要用“Logger.Log”填充代码?@DanielBalas上次我与PostSharp支持人员聊天时,有人告诉我PostSharp专业版不适用于express/community。如果Postsharp professional logging module可以与VS community一起使用,这对我来说已经足够好了。如果是关于错误/异常,让它冒泡到应用程序启动并在那里登录。如果需要添加仅在特定层可用的信息,只需在写入时将该信息添加到异常的“数据”属性和格式中即可。只能在一个位置使用日志记录。@MoatazElGamal嗯,由于Microsoft授权策略,Express不受支持。社区从2014年11月起就得到了充分支持。使用反射调用方法的性能成本可能相当高(尤其是在日志记录的情况下)。如果性能有问题,我建议使用Reflection.Emit/Linq表达式和缓存机制。
var logging = new Logging();
//inject logging aspect to SampleClass
logging.Manage<SampleClass>();
//now when SampleMethod is called, it is logged.