解决多重继承(对于预煮类)

时间:2013-02-20 11:45:19

标签: c#-4.0 multiple-inheritance proxy-classes context-bound

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

更详细的解释。

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

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

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

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

ServiceBase.Run(new MyService());

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

从我看到,从MarshalByRefObject扩展将扩展类放在ContextBoundObject中(可能因为这样方法调用使用SyncProcessMessage(IMessage),因此可以截获并记录),也许有一种方法可以在没有继承的情况下完成它,或者可能有一些预编译或后期编译技术可用于使用日志记录调用的周围方法(如T4文本模板),我不知道。

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

2 个答案:

答案 0 :(得分:0)

记录方法调用通常使用属性来注释要为其启用日志记录的类或方法。这称为Aspect Oriented Programming

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

对于C#,存在PostSharp。有关简介,请参阅here

答案 1 :(得分:0)

尝试使用代理我发现了一种明显记录显式调用的方法 基本上我在msdn中创建一个RealProxy例子,然后获取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的类进行测试。