只是想知道在什么情况下,当您可以使用ChannelFactory调用调用时,您希望从WCF服务生成代理?
这样您就不必生成代理并担心在服务器更新时重新生成代理?
由于
答案 0 :(得分:85)
创建WCF客户端有三种基本方法:
让Visual Studio生成您的代理。这会自动生成通过读取WSDL连接到服务的代码。如果服务因任何原因而更改,则必须重新生成它。这样做的最大优点是它易于设置 - VS有一个向导,它都是自动的。缺点是你依靠VS来为你做所有艰苦的工作,所以你失去了控制。
将ChannelFactory
与已知界面一起使用。这取决于您具有描述服务的本地接口(服务合同)。最大的优点是可以更轻松地管理变更 - 您仍然需要重新编译和修复更改,但现在您没有重新生成代码,您正在引用新接口。通常,当您控制服务器和客户端时都会使用它,因为两者都可以更容易地模拟单元测试。但是,可以为任何服务编写接口,甚至是REST服务 - 请查看this Twitter API。
编写自己的代理 - 使用HttpClient
或WebClient
,这很容易做到,特别是对于REST服务。这为您提供了最精细的颗粒控制,但代价是许多服务API都在字符串中。例如:var content = new HttpClient().Get("http://yoursite.com/resource/id").Content;
- 如果API的细节发生变化,您将不会在运行时遇到错误。
就我个人而言,我从来没有喜欢过选项1 - 依赖自动生成的代码很乱并且失去了太多的控制权。此外,它经常会产生序列化问题 - 我最终会得到两个相同的类(一个在服务器代码中,一个是自动生成的),这些类可以很长,但很痛苦。
选项2应该是完美的,但是频道有点限制 - 例如他们completely lose the content of HTTP errors。也就是说,拥有描述服务的接口更容易编码和维护。
答案 1 :(得分: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(如果可用)。这样,我可以根据自己的需要使用最好的绑定。我只依赖于服务器上存在元数据端点这一事实。
我希望这会有所帮助
BTW,这是使用.NET 3.5完成的。但它也适用于4.0。
答案 2 :(得分:11)
为了使用ChannelFactory<T>
,您必须愿意在服务和客户之间共享合同程序集。如果这对您没问题,那么ChannelFactory<T>
可以为您节省一些时间。
答案 3 :(得分:9)
代理将构建非常好的异步函数。
答案 4 :(得分:7)
我的回答是Keith's和Andrew Hare's答案的摘要。
如果您不控制服务器,但只使用Visual Studio或svcutil生成WSDL / URL-生成代理。 (请注意,当svcutil工作得更好时,Visual Studio有时会失败。)
当您控制服务器和客户端时,共享接口/合同并调用ChannelFactory
答案 5 :(得分:2)
这不只是节省时间的问题。使用WSDL生成的代理是危险的,因为如果您忘记更新服务引用,则可能会使解决方案处于不一致状态。一切都汇编但服务合同被打破。我绝对建议尽可能使用ChannelFactory,让你的生活更轻松。
一种可能的替代方法是编写一个prebuild脚本,在每次构建项目时调用SVCUtil实用程序来创建代理,但无论如何ChannelFactory更加整洁和优雅。