0

我需要的是:一个有两个父母的班级,他们是ContextBoundObject另一个班级。
为什么:我需要访问ContextBoundOject来记录方法调用。
作曲有效吗?截至目前,否(除其他外,无法识别类型)。
还有其他方法可以做到这一点吗?是的,但不是那么自动化并且没有第三方组件(也许 T4 可以做到,但我不是专家)。

更详细的解释。

我需要扩展 System 类(其中一些已经MarshalByRefObject(它是 的父级ContextBoundObject)作为父级,例如ServiceBaseand FileSystemWatcher,而有些没有,例如Exceptionand Timer)来访问框架的一些内部工作,所以我可以记录方法调用(现在;将来可能会改变)。

如果我使用这种方式,我只需向要记录的对象添加一个类名,而不是向每个方法添加记录调用,但显然我不能这样做:

public class MyService:ServiceBase,ContextBoundObject,IDisposable{
    public MyService(){}
    public Dispose(){}
}

所以可以尝试通常的解决方案,接口,但是如果我调用 Run 如下:

ServiceBase.Run(new MyService());

使用假设的接口 IServiceBase 它不起作用,因为类型 ServiceBase 不能转换为 IServiceBase - 它不继承任何接口。除了例外,问题更严重:throw只接受从Exception.
反过来,产生一个 IContextBoundObject 接口,似乎也不起作用:日志记录机制不能通过方法工作,所以我不需要实现任何,只需要一个属性和一些小的内部类(并且继承自ContextBoundObject,而不是甚至从MarshalByRefObject,元数据实际上是相同的)。

从我所看到的,扩展 fromContextBoundObject将扩展类放在一个Proxy(可能是因为在这种方式中方法调用使用 SyncProcessMessage(IMessage) 并且因此可以被拦截和记录),也许有一种方法可以在没有继承的情况下做到这一点,或者可能有是可用于带有日志调用的周围方法(如 T4 文本模板)的预编译技术或后编译技术,我不知道。

如果有人想看看这个,我在我的程序中使用了自定义版本的 MSTestExtentions 来记录(方法调用的)。任何想法表示赞赏。可能需要更多解释,请问。

4

2 回答 2

0

通过代理进行试验,我发现了一种明显记录显式调用的方法。
本质上,我RealProxy在 msdn 中创建了一个类似的示例,然后获取TransparentProxy并将其用作普通对象。
日志记录是在自定义类Invoke中覆盖的方法中完成的。RealProxy

static void Main(){
...
    var ServiceClassProxy=new ServiceRealProxy(typeof(AServiceBaseClass),new object[]{/*args*/});
    aServiceInstance=(AServiceBaseClass)ServiceClassProxy.GetTransparentProxy();
    ServiceBase.Run(aServiceInstance);
...
}

在代理类中,Invoke将这样做:

class ServiceRealProxy:RealProxy{
...
    [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.Infrastructure)]
    public override IMessage Invoke(IMessage myIMessage){
        // remember to set the "__Uri" property you get in the constructor
    ...
        /* logging before */
        myReturnMessage = ChannelServices.SyncDispatchMessage(myIMessage);
        /* logging after */
    ...
        return myReturnMessage;

        // it could be useful making a switch for all the derived types from IMessage; I see 18 of them, from
        // System.Runtime.Remoting.Messaging.ConstructionCall
        // ... to
        // System.Runtime.Remoting.Messaging.TransitionCall
    }
...
}

我仍然需要进行广泛的调查,但是发生了日志记录。这不是我最初问题的答案,因为我仍然需要在不继承自MarshalByRefObject.

于 2013-02-21T08:45:52.433 回答
0

记录方法调用通常使用属性来注释要启用记录的类或方法。这称为面向方面的编程

为此,您需要一个软件来理解这些属性并通过将必要的代码添加到已注释的方法/类来对您的程序集进行后处理。

对于 C#,存在PostSharp。请参阅此处了解介绍。

于 2013-02-20T11:49:11.357 回答