WCF ChannelFactory与生成代理

The*_*ies 81 wcf proxy channelfactory

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

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

谢谢

Kei*_*ith 86

创建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应该是完美的,但是频道有点限制 - 例如它们完全丢失了HTTP错误的内容.也就是说,拥有描述服务的接口更容易编码和维护.

  • @MurHaf不 - 这个答案完全是我自己的工作.我总是将其他人的贡献归因于此.我根据多年来在各种工作中使用.Net中的SOAP服务写了这个答案.您链接到的那篇文章是从2013年3月开始的,而我的答案是在2010年4月写的 - 3年前!如果发生剽窃,他就抄袭了我.你应该在指控之前检查日期,因为它很容易做到. (3认同)

Jea*_*eau 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()
Run Code Online (Sandbox Code Playgroud)

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

我希望这有帮助

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


And*_*are 11

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

  • @Aran:我认为Andrew的意思是正确的 - 如果你不想生成合同类的传真,那么你需要访问原件.确实,你需要有这样或那样的合同类.您可以生成它们,手动编写它们,或者获取服务源代码(如果它们使用相同的语言).共享程序集是最简单的方法,但这并不总是可行的.(也许我只是按字面意思对待安德鲁,但清晰度在这里很重要.) (6认同)
  • 事实并非如此. (2认同)
  • @Charles ok,所以你说你可以使用ChannelFactory <T>,即使你无法通过手工编写T接口然后使用它来访问程序集. (2认同)

Aar*_*her 9

代理将构建异常函数,这是很好的.

  • 是的 - 与此同时,Visual Studio的"添加服务引用"以及命令行上的svcutil.exe都会使您的配置无法识别....至少使用svcutil.exe,您可以定义"/ noconfig"开关..... (2认同)

MiF*_*vil 7

我的回答是KeithAndrew Hare的答案的总结.

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

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