引用相同数据协定的多个 WCF 服务

Posted

技术标签:

【中文标题】引用相同数据协定的多个 WCF 服务【英文标题】:Multiple WCF services referencing the same data contracts 【发布时间】:2011-01-20 14:13:27 【问题描述】:

我正在构建一组共享通用数据协定(或实体,如果您愿意)的 WCF 服务。这些是用 DataContract 和 DataMember 属性修饰的简单数据传输对象。我明确指定名称和命名空间。为了遵循 IDesign 建议的每个服务合同平均有 12 名成员的原则,我将我的服务项目分解为多个服务。

我的数据合同在一个单独的程序集中,如果他们使用 .Net,我可以将其提供给我们的客户。他们可以告诉他们的服务引用在引用的程序集中重用类型。但是,如果他们不使用 .net 并且他们使用 2 个服务,这两个服务都使用相同的实体,那么我假设他们会得到一个模棱两可的参考消息。如果我不引用数据协定 dll,我可以在 Visual Studio 中看到这一点。

我的问题是,我可以在我的服务中做些什么,或者他们可以在客户端应用程序中做些什么来绕过必须限定数据合同来自哪个代理?

【问题讨论】:

我也有同样的问题。我尝试使用下面文章中的建议,但没有任何乐趣。但是,我使用的是 WCF RESTful 服务(这可能与下面的方法不起作用有关),所以我最终只是引用了一个包含我的数据协定的通用 DLL,并将服务引用放在一起。由于我使用简单的 HTTP Web 请求调用我的服务,因此我实际上不需要项目中的服务引用。 【参考方案1】:

描述如何解决此问题的好文章。 Sharing DataContracts between WCF Services

【讨论】:

【参考方案2】:

我还倾向于将我的所有数据协定保存在一个程序集中,该程序集被多个服务和众多客户端应用程序引用,效果很好,但我从未尝试在 .NET 之外使用该服务。

了解他们使用什么技术来使用除 .NET 之外的服务可能会有所帮助?什么是抛出模棱两可的参考信息?

【讨论】:

您可以在 .net 中执行此操作,只是不要引用您的数据合约 dll 并观察会发生什么。创建一个测试项目,添加两个都使用通用数据协定作为引用的服务,您将收到模棱两可的消息。【参考方案3】:

我碰巧有多个共享对象的服务。我不确定你为什么会遇到这个问题。就我而言,我能够以这种方式访问​​对象。 . . .

SERVICE1 客户端 = 新 SERVICE1()

client.CommonLibrary.Address。 . .

SERVICE2 client2 = new SERVICE2()

client2.CommonLibrary.Address 。 . . .

【讨论】:

这也适用于我。关键是它们是两个不同的对象。消费应用程序不能只说 CommonLibrary.Address,它必须使用服务名称进行限定。这不是一个真正的问题,我只是想知道服务引用是否会检测到公共数据合同的相同命名空间并共享它。【参考方案4】:

这取决于他们在客户端使用的工具。例如,对于 Axis2 for Java,wsdl2java 工具可以通过使用 -u 开关来共享类型。

how can I share proxy objects across multiple Axis2 web service clients?

【讨论】:

【参考方案5】:

根据我的理解和使用 WCF 的情况,只要完全限定名称相同并且具有相同的数据成员,客户端应用程序使用的任一数据协定都无关紧要。在内部,它只是动态创建对象并使用公共设置器重新分配这些数据成员属性。

我认为一个更好的方法是重构你的数据契约,这样你就可以将多个服务中的所有共同点放入一个程序集中并引用它们,因此无论使用多少服务,你都不会遇到这种模棱两可或冲突的问题由客户端应用程序。

【讨论】:

Fadrian,我所有的数据合约都在一个程序集中。问题是如果 2 个服务引用相同的数据契约,每个服务都会获得它自己的命名空间版本。 Paul,您是否尝试在 DataContract 属性中明确指定命名空间?以及您是如何创建数据合约程序集的?您是否尝试使用 svcutil 工具并使用 /namespace: 参数手动生成数据控件?我个人没有遇到过这个问题,所以我可能没有点击正确的按钮,只是在这里分享一些想法。【参考方案6】:

我们不是通过 Visual Studio 助手生成服务代理,而是通过调用 slsvcutil.exe 的自定义批处理文件(因为我们使用 Silverlight)。在那里,您可以使用 /n 参数指定命名空间映射,如下所示:

"C:\Program Files (x86)\Microsoft SDKs\Silverlight\v5.0\tools\slsvcutil.exe "^
 http://ServiceUrl/MyService.svc^
 **/n:http://youruri.org/CustomerService/DataContracts,CLR.Namespace.CustomerService^**
 /n:*,CLR.Namepsace.MyService^
 /r:"%ProgramFilesFolder%\Reference Assemblies\Microsoft\Framework\Silverlight\v5.0\System.Windows.dll"^
 /ct:System.Collections.ObjectModel.ObservableCollection`1^
 /edb^

因此,所有具有命名空间http://youruri.org/CustomerService/DataContracts 的数据协定都会生成到代理文件中的 clr 命名空间 CLR.Namespace.CustomerService 等等。假设您已经在同一个代理程序集中预先生成了这个代理,您可以从第二个文件中删除整个命名空间,一切正常 - 我们为最后一步编写了一个小工具。所有其他合约命名空间都将生成到 CLR.Namepsace.MyService 命名空间(见星号含义)

设置过程有些麻烦,因为您必须手工制作批处理文件,但一旦完成,它就会运行良好。

【讨论】:

以上是关于引用相同数据协定的多个 WCF 服务的主要内容,如果未能解决你的问题,请参考以下文章

WCF - 使用完全相同的数据合同的多个服务合同

WCF 设计和实现服务协定(01)

添加服务引用时出错:类型是不支持的递归集合数据协定

在类库项目中添加 WCF 服务引用,并在使用该类库的网站中添加相同的 WCF 引用。

为 WCF 服务添加服务引用会生成空的 reference.cs

在多个 WCF 服务之间共享类