一个WCF服务能否返回另一个WCF服务?

4
例如,一个WCF服务是否可以作为其他WCF服务的工厂? 例如:
[ServiceContract(Namespace = "Foo")]
interface IThing
{
    [OperationContract]
    void DoSomething();
}

[ServiceContract(Namespace = "Foo")]
interface IMakeThings
{
    [OperationContract]
    IThing Create(string initializationData);
}

同样地,一个接口可以将另一个接口作为参数吗?
[ServiceContract(Namespace = "Foo")]
interface IUseThings
{
    [OperationContract]
    void UseThing(IThing target);
}

这需要调整已知的类型吗?

所有接口都将事先定义,并为客户端和服务方所知。


客户端有代理,而不是真正的服务实例。所以这个问题根本没有意义。 - Tony Kh
不,WCF是一种基于消息的系统 - 它仅传递XML序列化数据(仅限数据 - 没有代码或方法)从客户端到服务器并返回。它不是设计成类似远程调用或支持“远程对象调用”之类的东西。 - marc_s
1
我可能漏掉了什么,但理论上客户端可以根据与“IMakeThings”服务的绑定,在适当的“IThing”代理中包装IMakeThings.Create()的返回结果。这个问题的答案很可能是“不行”,这也没关系,但我认为这个问题本身是有意义的。 - WaffleSouffle
@marc_s 对我来说,数据以消息结构的XML序列化似乎并不影响调用远程对象的结果。对我来说,这看起来像是设置进一步的代理和绑定的问题。 - WaffleSouffle
客户是否知道“转发”服务实现的合同? - Richard Blewett
显示剩余2条评论
2个回答

8
  1. 不可以。当你在网上浏览时,你不像在C#中使用引用,所以你不能返回一个不可序列化的对象。即使这样,只有被标记为DataMember的数据才能被传输。

  2. 可以。你需要调整已知的类型,但这仅适用于一个接口到DataContract的过程,而不是OperationContract


我明白,但这就是WCF的工作方式。如果您想返回某种服务,那么它必须是一个自定义对象,其中包含有关该服务的信息(以及如何调用它的说明),而不是服务本身。在非WCF代码内部,这可以正常工作,因为您正在来回传递引用。在WCF上,它无法正常工作,因为您正在传递静态数据实例。通过命名管道可能是可能的,因为它会传递内存指针,但我持怀疑态度。 - Thinking Sites
现在,让我补充一下,如果您愿意,您可以设置一种方式,让您将指令发送回客户端,告诉他们其他可用的方法选项,最有可能是服务URL的字符串描述,以及方法签名,具体取决于您想如何处理。您的最终目标是可以实现的,只是您在问题中尝试的方式不太对。 - Thinking Sites
这非常有帮助(所以这可能会成为被接受的答案)。如果我理解正确,您建议的方法是服务启动另一个服务并返回端点(加上可能的其他信息)作为字符串,以便客户端可以使用ChannelFactory连接到该端点?如果是这样,我想我的最初问题是关于WCF和/或.NET库是否具有一些功能来减轻程序员的负担。这一切似乎都是可能的,只是有点棘手,通常意味着方法不正确... - WaffleSouffle
WCF旨在对系统不做任何偏见,这就是为什么你只能传递数据的原因。为此,我们可以将数据传递给PHP、Java、JavaScript等等。所以,是的,你试图做的事情很麻烦,因为它不是WCF的预期功能,也不是通常的正确方法。我想如果你正在使用SOAP,你也可以返回一个WSDL,这样客户端就可以构建服务客户端。无论如何,这基本上就是你要做的事情。如果你的服务器和客户端在同一台机器上,请尝试使用命名管道,它可能会非常有效。 - Thinking Sites
我并不考虑让服务“自启动”另一个服务,相反,我想要一个使用反射来读取其他服务足迹的服务,然后将所有内容作为字符串描述返回。再次强调,你真正需要的是一个 WSDL,因为那正是 WSDL 的作用,是一个服务的文本描述。如果我可以问一下,你为什么需要发送这种类型的数据呢?听起来对我来说,你有一个关于整体架构的更大问题,而不是如何解决这个具体的 WCF 问题。 - Thinking Sites
显示剩余4条评论

0

我认为这是不可能的。当您调用接受或返回对象的 WCF 服务上的方法时,实际发生的是对象被序列化并传递来回。

这就是为什么在客户端上,您不会得到带有 DataContract 属性类的“完整实现”,而只会得到一个仅包含标记为可序列化属性的存根。您甚至不会得到方法。WCF 服务被标记为 ServiceContract,而不是 DataContract,因此这根本行不通。

使用接口传递给服务方法的能力需要服务知道要反序列化哪个实现。虽然我实际上还没有尝试过,但我想这不会起作用,但您可能会在这里让我感到惊讶 :-)


我相信你是正确的,但是作为一个反例,有回调合同用于服务回调到客户端,这需要明确的管道代码,但是它是通过接口将服务传递给另一个服务的示例。我不是很在意数据序列化,而是基于现有绑定设置进一步代理。 - WaffleSouffle
我认为回调合同不是那样工作的。我猜他们没有传递回调服务的实例,而是客户端也透明地设置了一个WCF服务。 - Thorsten Dittmar
您可以轻松地为现有绑定设置更多服务。您只需在配置中声明第二个服务,使其使用相同的绑定,但附加到URI即可。例如,您的第一个服务的URI是net.tcp://localhost:8080/MyService/Service1,您可以简单地在URI net.tcp://localhost:8080/MyService/Service2 上拥有第二个服务(相同的端口,相同的基本URI!)。 - Thorsten Dittmar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接