我正在尝试编写泛型方法,所有wcf代理方法都通过此方法并缓存返回值。通用方法是
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(string 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 :(得分: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必须具有实例参数,根据.DynamicInvoke调用,您将通道作为第一个参数传递,然后是实际的方法参数:
delegate void myMethodDelegateX(IMyInterf targetInstance, T1 arg1, T2 arg2, ...);
我在关于Delegate.CreateDelegate(Type,Object,MethodInfo)重载的MSDN文档中发现了这个变体,它被称为&#34; open instance&#34;那里的方法,它适用于我的WCF频道,我总是得到&#34;无法绑定到目标方法......&#34;
编辑:当然d.DynamicInvoke(channel,args)是无意义的,你必须将这些参数放入一个新的数组中。