2014-11-04 51 views
0

我正在尝试编写所有wcf代理方法都通过此方法并缓存返回值的泛型方法。通用方法是创建动态委托WCF TransparentProxy

public T CallService<T>(Delegate del, object[] args) 
{ 
    // begin caching logic 
    // ... 
    // if value is cached, return it. Otherwise call app site.  
    // end caching logic 
    return (T)del.DynamicInvoke(args); 
} 

为了实现这一点,我需要通过下面的链接动态创建委托。

Creating delegates dynamically with parameter names

简单地说我要的是为信道的方法IFooService.Bar(字符串PARAM)创建委托。

//wcf contract 
public interface IFooService 
{ 
    int Bar(string param); 
} 

//sample proxy 
public class Foo 
{ 
    public int Bar(string param) 
    { 
     IFooService channel = null; 
     int result; 
     try 
     { 
      // we assume that wcf channel has created here 
      ChannelFactory<IFooService> channelFactory = new ChannelFactory<IFooService>(binding, remoteAddress); 
      IFooService channel = channelFactory.CreateChannel(); 

      var parameters = MethodBase.GetCurrentMethod().GetParameters(); 
      object[] args = new object[parameters.Length]; 
      args[0] = param;   

      MethodInfo method = typeof(IFooService).GetMethod("Bar"); 
      Delegate del = CreateDelegate(channel, method); 

      result = CallService<int>(del, args); 
      ((ICommunicationObject)channel).Close(); 
     } 
     catch (Exception ex) 
     { 
      ((ICommunicationObject)channel).Abort(); 
      throw; 
     } 
     return result; 
    } 
} 

当应用程序运行时,我在“Delegate del = CreateDelegate(channel,method)”这一行得到异常。

Cannot bind to the target method because its signature or security transparency is not compatible with that of the delegate type. 
     at System.Delegate.CreateDelegate(Type type, Object firstArgument, MethodInfo method, Boolean throwOnBindFailure) 

我相信方法签名是正确的。

通道对象的确切类型是System.Runtime.Remoting.Proxies .__ TransparentProxy。但是,channel.getType()返回IFooService。这怎么可能?这种情况背后的魔术是什么?我不知道该模式提供了这个解决方案以及__TransparentProxy如何工作。有没有代码(项目)示例演示这种架构?我认为这就是为什么动态委托创建不能绑定目标方法。

+0

我被困在同一点 – Gandarez 2015-03-20 12:59:18

回答

1

我得到了同样的异常,当我试图

MethodInfo mi = typeof(IMyInterf).GetMethod(MyMethod); 
Delegate d = Delegate.CreateDelegate(typeof(myMethodDelegate), channel, mi); 
d.DynamicInvoke(args); 

,当我将其更改为它的工作原理:

Delegate d = Delegate.CreateDelegate(typeof(myMethodDelegateX), null, mi); 
d.DynamicInvoke(channel, args); 

如果myMethodDelegate看起来像

delegate void myMethodDelegate(T1 arg1, T2 arg2, ...); 

然后myMethodDelegateX必须有将通道作为第一个参数传递给它的实例参数,然后是实际的方法参数S,根据.DynamicInvoke呼叫:

delegate void myMethodDelegateX(IMyInterf targetInstance, T1 arg1, T2 arg2, ...); 

我发现了Delegate.CreateDelegate(类型,对象,MethodInfo的)过载,它被称为一个“打开的实例”的方法有,与MSDN文档在该变型它适用于我的WCF频道,我总是得到“不能绑定到目标方法...”

编辑:当然d.DynamicInvoke(渠道,参数)是无稽之谈,你必须把这些参数放入一个新的数组。