Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# .NET-拦截不带继承或Postsharp的对象_C#_.net_Postsharp_Aop - Fatal编程技术网

C# .NET-拦截不带继承或Postsharp的对象

C# .NET-拦截不带继承或Postsharp的对象,c#,.net,postsharp,aop,C#,.net,Postsharp,Aop,我希望使用拦截在我的应用程序中添加日志记录,而不必在代码中填充以下行: “Logger.Log(某物);” 我知道这被认为是一个“交叉关注点”,这意味着可以使用面向方面的编程很好地处理它。 我考虑了以下两个不适合我的选择。 1-Postsharp:不能在社区版上使用 2-Unity框架:提供接口拦截、虚拟方法和MarshalByRef继承。这些选项都不起作用,因为我无法为项目中的每个类编写新接口。我不能使所有方法都是虚拟的,也不能破坏继承结构并将继承限制为MarshalByRef 我可能想错了这

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

我知道这被认为是一个“交叉关注点”,这意味着可以使用面向方面的编程很好地处理它。 我考虑了以下两个不适合我的选择。 1-Postsharp:不能在社区版上使用 2-Unity框架:提供接口拦截、虚拟方法和MarshalByRef继承。这些选项都不起作用,因为我无法为项目中的每个类编写新接口。我不能使所有方法都是虚拟的,也不能破坏继承结构并将继承限制为MarshalByRef

我可能想错了这个问题。提前感谢您的帮助。

请看一下课程。您可以很容易地使用它来实现decorator模式:

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.