2013-07-03 56 views
1

我試圖創建RealProxy以實現一些緩存和一些其他功能。我檢查了GetTransparentProxy返回的類型,它看起來是正確的,但是如果我在它上調用InvokeMember,那麼代理最終會自行調用,並且會發生堆溢出。請有人指出我做錯了什麼?RealProxy的實現以無限循環結束

public class CachedWebServiceProxy<T> : RealProxy 
{ 
    private Type _typeOfProxy; 
    public CachedWebServiceProxy(Type typeOfProxy) : base(typeOfProxy) 
    { 
     _typeOfProxy = typeOfProxy; 
    } 
    public override System.Runtime.Remoting.Messaging.IMessage Invoke(System.Runtime.Remoting.Messaging.IMessage msg) 
    { 
     var methodCall = msg as IMethodCallMessage; 
     var methodInfo = methodCall.MethodBase as MethodInfo; 

     var proxy = GetTransparentProxy(); 
     var result = _typeOfProxy.InvokeMember(methodCall.MethodName, BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Instance, null, proxy, methodCall.Args); 
     return new ReturnMessage(result, null, 0, methodCall.LogicalCallContext, methodCall); 
    } 
} 

class CachedWebServiceChannelFactory<T> : ChannelFactory<T> 
{ 
    public CachedWebServiceChannelFactory(Binding binding, EndpointAddress endpoint) : base(binding, endpoint) 
    { } 

    public CachedWebServiceChannelFactory(string endpointConfigurationName) 
     : base(endpointConfigurationName) 
    { } 

    public override T CreateChannel(EndpointAddress address, Uri via) 
    { 
     var extendedProxy = new CachedWebServiceProxy<T>(typeof(T)); 
     return (T)extendedProxy.GetTransparentProxy(); 
    } 
} 
+0

如果你解決它自己,你可以(也應該)發佈您的解決方案作爲一個答案,而不是編輯的問題。 – Flexo

回答

1

好的,基本的問題是,我認爲我的代碼包裝透明代理時,實際上透明代理包裝我的類。我認爲我能做的就是創建一個基本代理的實例,在這個代理上調用方法並返回結果。

因爲我的課實際上是透明代理調用GetTransparentProxy剛剛創建我的類的新實例的基類(這反過來又創造了另一個新的實例等)

我現在意識到,我應該已經做了相似的東西,但在ChannelFactory內。這是一個子類,所以我可以用我自己的邏輯來包裝base。*方法,就像我希望在代理類中做的那樣。我現在要做的是從基本方法獲取通道實例,然後將其傳遞給我的RealProxy類,然後使用反射在通道對象上調用所需的方法。

下面是代碼:

public class CachedWebServiceProxy<T> : RealProxy 
{ 
    private Type _typeOfProxy; 
    public object _channel; 
    public CachedWebServiceProxy(Type typeOfProxy, object channel) 
     : base(typeOfProxy) 
    { 
     _typeOfProxy = typeOfProxy; 
     _channel = channel; 
    } 
    public override System.Runtime.Remoting.Messaging.IMessage Invoke(System.Runtime.Remoting.Messaging.IMessage msg) 
    { 
     var methodCall = msg as IMethodCallMessage; 
     var methodInfo = methodCall.MethodBase as MethodInfo; 
     object result = null; 
     result = methodInfo.Invoke(_channel, methodCall.Args); 
     return new ReturnMessage(result, null, 0, methodCall.LogicalCallContext, methodCall); 
    } 
} 


public class CachedWebServiceChannelFactory<T> : ChannelFactory<T> 
{ 
    public CachedWebServiceChannelFactory(Binding binding, EndpointAddress endpoint) 
     : base(binding, endpoint) 
    { } 

    public CachedWebServiceChannelFactory(string endpointConfigurationName) 
     : base(endpointConfigurationName) 
    { } 

    public override T CreateChannel(EndpointAddress address, Uri via) 
    { 
     T innerChannel = base.CreateChannel(address, via); 
     var extendedProxy = new CachedWebServiceProxy<T>(typeof(T), innerChannel); 
     return (T)extendedProxy.GetTransparentProxy(); 
    } 
}