在WCF中使用代理序列化委托?
我有一个想法,但我需要帮助实现它 WCF在其合同中不支持委托。 相反,它有一个麻烦的回调契约机制,我正在寻找一种方法来克服这个限制 我考虑使用一个在WCF中使用代理序列化委托?,wcf,delegates,datacontract,Wcf,Delegates,Datacontract,我有一个想法,但我需要帮助实现它 WCF在其合同中不支持委托。 相反,它有一个麻烦的回调契约机制,我正在寻找一种方法来克服这个限制 我考虑使用一个IDataContractSurrogate将契约中的每个委托替换为一个令牌,该令牌将被序列化到远程端点。在那里,令牌将反序列化为生成的委托。此生成的委托将发送一条通用回调消息,该消息封装了所有参数(调用委托时使用的参数) 通用回调消息将到达第一个端点,并在那里使用参数调用原始委托 以下是目的(简化)顺序: A调用B-proxy.Foo(回调) 回调通
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);
}
//客户端
remoteSvc.GetEmployeeById(17,emp=>
{
添加(emp);
logger.log(“收到结果”);
});
//服务器端
public void GetEmployeeById(int-id,操作回调)
{
var emp=getEmpFromDb(id);
回调(emp);
}
实际上,在这个场景中,我将研究表达式
API。与委托不同,表达式可以在运行时解构。默认情况下,您无法序列化它们,但已在该空间中完成了一次序列化。这也有点像许多LINQ提供者在后台所做的,例如WCF数据服务
当然,另一种方法是简单地使用lambda表达式作为RPC的钩子,这就是我所描述的。实现这一点的代码在protobuf网络树中免费提供。您可以使用一个属性将您的令牌与方法关联,并从MethodInfo
中获取该属性,从而对此进行自定义
在我看来,委托的问题在于,它们与实现的耦合太紧密,因此不能在每一端都有不同的实现(这是一个常见的需求)
表达式的优点是lambdas仍然支持intellisense等,因此您可以执行以下操作:
client.Invoke(svc => svc.Foo(123, "abc"));
从中分别获得Foo
(theMethodInfo
)、123和“abc”,包括捕获的变量、ref
/out
,等等。这一切都是有效的。为什么标准回调机制“麻烦”?因为您需要样板代码来使用它,您需要学习这种机制。另外,我不相信它会在像MSMQ这样的单向渠道中起作用。作为回调的代理更直观,因为它们看起来像普通的C#代码。谢谢你的回答,但这不是我想要的。首先,表达式树不是具有语句体的lambda的选项。其次,我仍然不知道如何编写我的代理并将其连接到WCF。我将在主帖中添加一个示例用例,以使其更加清晰。@Omer-在4.0中,Expression
支持语句体。C#编译器不支持它,但表达式支持它。这是可以做到的。如果编译器不支持它,那就没用了。看看我的示例用法,看看我在追求什么。我仍然认为没有必要序列化委托和/或表达式。我们所需要的只是一个特殊的令牌,并将委托存储在客户端,直到服务器端调用“代理委托”。@Omer-您给出的示例在C#中很好用-连接上的东西不是语句体。如果你不想那样做:好的。但是我知道这是可行的。是的,这个例子没有使用语句体,因为我希望我的需求简洁明了。但我现在改了。