WCF ChannelFactory与生成代理

想知道在什么情况下,你可以使用ChannelFactory来调用调用时,你更愿意从WCF服务中生成一个代理?

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

谢谢

有三种基本的方法来创build一个WCF客户端:

  1. 让Visual Studio生成您的代理。 这个自动生成通过读取WSDL连接到服务的代码。 如果服务因任何原因而更改,则必须重新生成该服务。 这样做的一大优势就是设置起来很简单 – VS有一个向导,而且全是自动的。 缺点是你依靠VS来为你做所有的辛苦工作,所以你失去了控制权。

  2. 使用带有已知接口的ChannelFactory 。 这依赖于你有描述服务的本地接口(服务契约)。 最大的好处是可以更容易地pipe理变更 – 您仍然需要重新编译和修改变更,但现在您不再重新生成代码,而是引用了新的接口。 通常这是在你控制服务器和客户端时使用的,因为对于unit testing来说都可以更容易地进行模拟。 然而,接口可以被编写为任何服务,甚至REST的 – 看看这个Twitter的API 。

  3. 编写自己的代理 – 这是相当容易做的,特别是对于REST服务,使用HttpClientWebClient 。 这给你提供了最好的谷物控制,但是代价是大量的服务API在string中。 例如: var content = new HttpClient().Get("http://yoursite.com/resource/id").Content; – 如果API的细节发生变化,则直到运行时才会遇到错误。

我个人从来没有喜欢选项1 – 依靠自动生成的代码是凌乱的,失去太多的控制。 此外,它经常会产生序列化问题 – 我最终得到了两个相同的类(一个在服务器代码中,一个是自动生成的),这个类可以被使用,但是很痛苦。

选项2应该是完美的,但频道有点太有限 – 例如他们完全失去了HTTP错误的内容 。 这就是说,描述服务的接口更容易编码和维护。

我使用ChannelFactory和MetadataResolver.Resolve方法。 客户端configuration是一个麻烦,所以我从服务器得到我的ServiceEndpoint。

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

为我使用ChannelFactory的主要目的是摆脱WCF客户端configuration信息。 在下面的示例代码中,您可以看到如何在没有configuration的情况下实现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。

那么为了使用ChannelFactory<T>你必须愿意在服务和客户之间共享合约汇编。 如果这样可以,那么ChannelFactory<T>可以节省一些时间。

代理将构buildasynchronousfunction,这是很好的。

我的回答是Keith和Andrew Hare的答案的总结。

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

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

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

一个可能的select可能是编写一个预编译脚本,每次构build项目时调用SVCUtil实用程序来创build代理,但无论如何ChannelFactory更加整洁优雅。