3

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

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

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

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

这是有目的的(简化的)序列:

  1. A 调用 B-pr​​oxy.Foo(callback)
  2. 回调通过 DelegateSurrogate 序列化。
  3. DelegateSurrogate 将委托存储在专用委托存储中,并用令牌替换它
  4. 消息到达 B 的端点
  5. 令牌通过 DelegateSurrogate 反序列化
  6. DelegateSurrogate 构造一个生成的委托
  7. B.Foo(generatedCallback) 被调用
  8. 稍后,B 正在调用 generatedCallback(args)
  9. generatedCallback(args) 在 A 的端点上调用一个专用的通用合约:CallbackContract-proxy.GenericCallback(args)
  10. 在 A 的端点上调用 CallbackContract.GenericCallback(args)
  11. 从存储中检索原始回调并调用:callback(args)

NServiceBus我之前已经使用服务总线(我知道如何实现步骤 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);
}
4

1 回答 1

2

实际上,在这种情况下,我会研究ExpressionAPI。与委托不同,Expression可以在运行时解构。默认情况下您无法对它们进行序列化,但是在该空间中已经完成了很多工作。这也有点像许多 LINQ 提供程序在后台执行的操作,例如 WCF 数据服务。

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

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

表达式的优势在于 lambda 仍然支持智能感知等,因此您可以执行以下操作:

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

并从中分别获得Foo(the MethodInfo)、123 和 "abc",包括捕获的变量ref/out等。这一切都有效。

于 2010-07-10T09:35:10.077 回答