使用代理项在WCF中序列化代理?

时间:2010-06-27 19:56:24

标签: wcf delegates datacontract

我有一个想法,但我需要帮助实现它。

WCF不支持其合同中的代表。 相反,它有一个繁琐的回调合约机制,我正在寻找一种克服这种限制的方法。

我考虑使用IDataContractSurrogate来替换合同中的每个委托,并使用将序列化到远程端点的令牌。在那里,令牌将被反序列化为生成的委托。这个生成的委托将发送一个通用的回调消息,该消息封装了所有参数(委托被调用的参数)。

通用回调消息将到达第一个端点,并且将使用参数调用原始委托。

这是目的(简化)序列:

  1. A调用B-proxy.Foo(回调)
  2. 回调通过DelegateSurrogate序列化。
  3. DelegateSurrogate将委托存储在专用委托存储中,并将其替换为令牌
  4. 消息到达B的端点
  5. 通过DelegateSurrogate
  6. 反序列化令牌
  7. DelegateSurrogate构造生成的委托
  8. 调用B.Foo(generatedCallback)
  9. 稍后,B正在调用generatedCallback(args)
  10. generatedCallback(args)在A的端点上调用专用通用契约:CallbackContract-proxy.GenericCallback(args)
  11. 在A的端点上调用CallbackContract.GenericCallback(args)
  12. 从存储中检索原始回调并调用:callback(args)
  13. 我之前已经使用服务总线(NServiceBus)实现了这个,但是我想让这个想法适应WCF并且我很难过。我知道如何实现步骤3,6,9和11.我还不知道如何在WCF中连接所有内容 - 尤其是代理部分。

    就是这样 - 我希望我的问题有道理,而且这里的集体智慧将能够帮助我建立起来。

    以下是我所需解决方案的示例用法:

    // client side
    remoteSvc.GetEmployeeById(17, emp => 
    {
        employees.Add(emp);
        logger.log("Result received");
    });
    
    // server side
    public void GetEmployeeById(int id, Action<Employee> callback)
    {
        var emp = getEmpFromDb(id);
        callback(emp);
    }
    

1 个答案:

答案 0 :(得分:2)

实际上,在这种情况下,我会查看Expression API。与委托不同,Expression可以在运行时解构。您无法在默认情况下序列化 ,但在该空间中已完成lot of work。它也有点像许多LINQ提供商在后台做的事情,例如WCF数据服务。

当然,另一种方法是简单地使用lambda表达式作为RPC的钩子,这就是我所描述的here。实现它的代码可以在protobuf-net树中免费获得。您可以使用属性将令牌与方法相关联,并从MethodInfo获取属性来自定义此项。

IMO,委托的问题在于它们与实现过于紧密耦合,因此您不能在每一端都有不同的实现(这是一个常见的要求)。

表达式的优点是lambdas仍然支持intellisense等,所以你可以做以下事情:

client.Invoke(svc => svc.Foo(123, "abc"));

并从中获取FooMethodInfo),123和“abc”,包括捕获的变量,ref / out等等。一切正常。