Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/ms-access/4.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
Wcf RealProxy的实现以无限循环结束_Wcf - Fatal编程技术网

Wcf RealProxy的实现以无限循环结束

Wcf RealProxy的实现以无限循环结束,wcf,Wcf,我试图创建一个RealProxy来实现一些缓存和其他一些功能。我已经检查了GetTransparentProxy返回的类型,它看起来是正确的,但是如果我在它上面调用InvokeMember,那么代理最终会调用自己,我会得到一个堆溢出。有人能指出我做错了什么吗 public class CachedWebServiceProxy<T> : RealProxy { private Type _typeOfProxy; public CachedWebServiceProx

我试图创建一个RealProxy来实现一些缓存和其他一些功能。我已经检查了GetTransparentProxy返回的类型,它看起来是正确的,但是如果我在它上面调用InvokeMember,那么代理最终会调用自己,我会得到一个堆溢出。有人能指出我做错了什么吗

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();
    }
}
公共类CachedWebServiceProxy:RealProxy
{
私有类型_typeOfProxy;
公共缓存WebServiceProxy(类型typeOfProxy):基本(类型OfProxy)
{
_typeOfProxy=typeOfProxy;
}
公共覆盖System.Runtime.Remoting.Messaging.IMessage调用(System.Runtime.Remoting.Messaging.IMessage msg)
{
var methodCall=msg作为IMethodCallMessage;
var methodInfo=methodCall.MethodBase作为methodInfo;
var proxy=GetTransparentProxy();
var result=_typeOfProxy.InvokeMember(methodCall.MethodName,BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Instance,null,proxy,methodCall.Args);
返回新的ReturnMessage(结果,null,0,methodCall.LogicalCallContext,methodCall);
}
}
类CachedWebServiceChannelFactory:ChannelFactory
{
公共CachedWebServiceChannelFactory(绑定绑定,端点地址端点):基(绑定,端点)
{ }
公共缓存WebServiceChannelFactory(字符串endpointConfigurationName)
:base(endpointConfigurationName)
{ }
公共覆盖T CreateChannel(端点地址,Uri通过)
{
var extendedProxy=new CachedWebServiceProxy(typeof(T));
return(T)extendedProxy.GetTransparentProxy();
}
}

好的,基本问题是我假设我的代码正在包装透明代理,而实际上透明代理正在包装我的类。我想我能做的就是创建一个基本代理的实例,调用这个代理上的方法并返回结果

因为我的类实际上是透明代理调用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();
    }
}
公共类CachedWebServiceProxy:RealProxy
{
私有类型_typeOfProxy;
公共对象"频道;;
公共CachedWebServiceProxy(类型typeOfProxy,对象通道)
:基本(Proxy类型)
{
_typeOfProxy=typeOfProxy;
_通道=通道;
}
公共覆盖System.Runtime.Remoting.Messaging.IMessage调用(System.Runtime.Remoting.Messaging.IMessage msg)
{
var methodCall=msg作为IMethodCallMessage;
var methodInfo=methodCall.MethodBase作为methodInfo;
对象结果=空;
结果=methodInfo.Invoke(_通道,methodCall.Args);
返回新的ReturnMessage(结果,null,0,methodCall.LogicalCallContext,methodCall);
}
}
公共类CachedWebServiceChannelFactory:ChannelFactory
{
公共CachedWebServiceChannelFactory(绑定绑定,端点地址端点)
:base(绑定,端点)
{ }
公共缓存WebServiceChannelFactory(字符串endpointConfigurationName)
:base(endpointConfigurationName)
{ }
公共覆盖T CreateChannel(端点地址,Uri通过)
{
T innerChannel=base.CreateChannel(地址,via);
var extendedProxy=new CachedWebServiceProxy(typeof(T),innerChannel);
return(T)extendedProxy.GetTransparentProxy();
}
}

Joe

好的,基本问题是我假设我的代码正在包装透明代理,而实际上透明代理正在包装我的类。我想我能做的就是创建一个基本代理的实例,调用这个代理上的方法并返回结果

因为我的类实际上是透明代理调用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();
    }
}
公共类CachedWebServiceProxy:RealProxy
{
私有类型_typeOfProxy;
公共对象"频道;;
公共CachedWebServiceProxy(类型typeOfProxy,对象通道)
:基本(Proxy类型)
{
_typeOfProxy=typeOfProxy;
_通道=通道;
}
公共覆盖System.Runtime.Remoting.Messaging.IMessage调用(System.Runtime.Remoting.Messaging.IMessage msg)
{
var methodCall=msg作为IMethodCallMessage;
var methodInfo=methodCall.MethodBase作为methodInfo;
对象结果=空;
结果=methodInfo.Invoke(_通道,methodCall.Args);
返回新的ReturnMessage(结果,null,0,methodCall.LogicalCallContext,methodCall);
}
}
公共类CachedWebServiceChannelFactory:ChannelFactory
{
公共CachedWebServiceChannelFactory(绑定绑定,端点地址端点)
:base(绑定,端点)
{ }
公共缓存WebServiceChannelFactory(字符串endpointConfigurationName)
:base(endpointConfigurationName)
{ }
公共覆盖T CreateChannel(端点地址,Uri通过)
{
T innerChannel=base.CreateChannel(地址,via);
var extendedProxy=newc