82

只是想知道当您可以使用 ChannelFactory 调用调用时,您更愿意在什么情况下从 WCF 服务生成代理?

这样您就不必生成代理并担心在服务器更新时重新生成代理?

谢谢

4

6 回答 6

88

创建 WCF 客户端有 3 种基本方法:

  1. 让 Visual Studio 生成您的代理。此自动生成通过读取 WSDL 连接到服务的代码。如果服务因任何原因发生更改,您必须重新生成它。这样做的最大优点是易于设置 - VS 有一个向导并且它是自动的。缺点是您依靠 VS 为您完成所有艰苦的工作,因此您失去了控制。

  2. ChannelFactory与已知接口一起使用。这依赖于您拥有描述服务的本地接口(服务合同)。最大的优势是可以更轻松地管理更改 - 您仍然需要重新编译和修复更改,但现在您不是重新生成代码,而是引用新接口。这通常在您同时控制服务器和客户端时使用,因为两者都可以更容易地模拟以进行单元测试。然而,可以为任何服务编写接口,甚至是 REST 服务——看看这个 Twitter API

  3. 编写您自己的代理 - 这很容易做到,尤其是对于 REST 服务,使用HttpClientWebClient. 这为您提供了最精细的控制,但代价是大量服务 API 位于字符串中。例如:var content = new HttpClient().Get("http://yoursite.com/resource/id").Content;- 如果 API 的详细信息发生更改,直到运行时您才会遇到错误。

就我个人而言,我从不喜欢选项 1 - 依赖自动生成的代码很混乱并且失去了太多的控制权。另外,它经常会产生序列化问题——我最终得到了两个相同的类(一个在服务器代码中,一个是自动生成的),这可以解决但很痛苦。

选项 2 应该是完美的,但 Channels 有点过于局限——例如​​它们完全丢失了 HTTP 错误的内容。也就是说,拥有描述服务的接口更容易编码和维护。

于 2010-04-06T08:01:49.137 回答
21

我使用 ChannelFactory 和 MetadataResolver.Resolve 方法。客户端配置很麻烦,所以我从服务器获取我的 ServiceEndpoint。

当您使用 ChannelFactory(Of T) 时,T 可以是您可以从项目中的引用中获得的原始合同,也可以是生成的合同实例。在某些项目中,我从服务引用生成代码,因为我无法添加对合约 dll 的引用。您甚至可以使用服务引用生成异步合约,并将该合约接口与 ChannelFactory 一起使用。

对我来说使用 ChannelFactory 的主要目的是摆脱 WCF 客户端配置信息。在下面的示例代码中,您可以看到如何在没有配置的情况下实现 WCF 客户端。

Dim fixedAddress = "net.tcp://server/service.svc/mex"
Dim availableBindings = MetadataResolver.Resolve(GetType(ContractAssembly.IContractName), New EndpointAddress(fixedAddress))
factoryService = New ChannelFactory(Of ContractAssembly.IContractName)(availableBindings(0))
accesService = factoryService.CreateChannel()

在我的最终项目中,检查了 availableBindings 以使用 net.tcp 或 net.pipe(如果可用)。这样,我就可以根据需要使用最好的可用绑定。我只依赖于服务器上存在元数据端点这一事实。

我希望这有帮助

顺便说一句,这是使用 .NET 3.5 完成的。但是它也适用于 4.0。

于 2011-01-27T14:45:07.473 回答
11

好吧,为了使用ChannelFactory<T>,您必须愿意在服务和客户端之间共享合同程序集。如果这对您来说没问题,那么ChannelFactory<T>可以为您节省一些时间。

于 2009-11-08T23:21:30.900 回答
9

代理将构建异步功能,这很不错。

于 2009-11-09T01:19:29.977 回答
8

我的回答是对KeithAndrew Hare回答的一种总结。

如果您不控制服务器,但只有 WSDL/URL-使用 Visual Studio 或 svcutil 生成代理。(请注意,当 svcutil 工作得更好时,Visual Studio 有时会失败)。

当您同时控制服务器和客户端时,共享接口/合同并调用 ChannelFactory

于 2012-01-21T21:40:37.500 回答
2

这不仅仅是节省时间的问题。使用 WSDL 生成的代理是危险的,因为如果您忘记更新服务引用,您可能会使解决方案处于不一致的状态。一切都编译了,但服务合同被打破了。我明确建议尽可能使用 ChannelFactory ,您可以让您的生活更轻松。

一种可能的替代方法是编写一个预构建脚本,该脚本在每次构建项目时调用 SVCUtil 实用程序来创建代理,但无论如何 ChannelFactory 更加简洁和优雅。

于 2015-04-18T14:23:53.703 回答