创建动态委托WCF TransparentProxy

本文关键字:WCF TransparentProxy 动态 创建 | 更新日期: 2023-09-27 18:29:09

我正在尝试编写一个通用方法,让所有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);
}

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

使用参数名称动态创建委托

简单地说,我想要的是为通道方法IFooService.Bar(字符串参数)创建委托。

//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(通道,方法)"行得到异常。

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)

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

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

创建动态委托WCF TransparentProxy

我在尝试时遇到了同样的异常

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文档中找到了这个变体,它在那里被称为"开放实例"方法,它与我的WCF通道一起工作,在那里我总是得到"无法绑定到目标方法…"

EDIT:当然。DynamicInvoke(通道,args)是无稽之谈,您必须将这些参数放入一个新数组中。