只是想知道在什么情况下仅使用ChannelFactory调用调用时,您希望从WCF服务生成代理?
这样,您将不必生成代理,也不必担心在服务器更新时重新生成代理吗?
谢谢
Answers:
创建WCF客户端的基本方法有3种:
让Visual Studio生成您的代理。通过读取WSDL,此自动生成连接到服务的代码。如果服务由于任何原因发生变化,则必须重新生成它。这样做的最大好处是易于设置-VS具有向导,并且完全是自动的。缺点是您依靠VS为您完成所有艰苦的工作,因此您会失去控制。
使用ChannelFactory
具有已知的接口。这取决于您具有描述服务(服务合同)的本地接口。最大的优点是可以更轻松地管理更改-您仍然必须重新编译和修复更改,但是现在您不是在重新生成代码,而是在引用新接口。通常,当您同时控制服务器和客户端时,会使用此方法,因为可以更轻松地对两者进行单元测试。但是,可以为任何服务(甚至是REST服务)编写接口-请查看此Twitter API。
编写自己的代理-使用HttpClient
或,这很容易做到,特别是对于REST服务WebClient
。这为您提供了最精细的控制,但是以字符串中的大量服务API为代价。例如:var content = new HttpClient().Get("http://yoursite.com/resource/id").Content;
-如果API的详细信息发生变化,则直到运行时您都不会遇到错误。
就我个人而言,我从来不喜欢选项1-依靠自动生成的代码是混乱的,并且失去了太多控制权。再加上它经常会引起序列化问题-我最终得到了两个相同的类(服务器代码中的一个,一个自动生成的),这些类可以被束缚起来,但是很痛苦。
选项2应该是完美的,但是Channels有点过于局限-例如,它们完全丢失了HTTP错误的内容。也就是说,拥有描述服务的接口更容易编写和维护。
我将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。
The main point of using ChannelFactory to get rid of the WCF client config
为了使用它,ChannelFactory<T>
您必须愿意在服务和客户端之间共享合同程序集。如果可以的话,ChannelFactory<T>
可以为您节省一些时间。
代理将建立异步函数,这对于它来说是一个不错的选择。
我的回答是对Keith和Andrew Hare的回答的一种总结。
如果您不控制服务器,而只有WSDL / URL,则使用Visual Studio或svcutil生成代理。(请注意,当svcutil更好地工作时,Visual Studio有时会失败)。
当您同时控制服务器和客户端时,共享接口/合同并调用ChannelFactory
。