我有一个想法,但我需要帮助实现它。
WCF不支持其合同中的代表。 相反,它有一个繁琐的回调合约机制,我正在寻找一种克服这种限制的方法。
我考虑使用IDataContractSurrogate
来替换合同中的每个委托,并使用将序列化到远程端点的令牌。在那里,令牌将被反序列化为生成的委托。这个生成的委托将发送一个通用的回调消息,该消息封装了所有参数(委托被调用的参数)。
通用回调消息将到达第一个端点,并且将使用参数调用原始委托。
这是目的(简化)序列:
我之前已经使用服务总线(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);
}
答案 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"));
并从中获取Foo
(MethodInfo
),123和“abc”,包括捕获的变量,ref
/ out
等等。一切正常。