生成WCF代理与ChannelFactory

5

这两种使用WCF服务的方式,哪一种更好?为什么?

  1. 从服务引用中生成代理
  2. 使用ChannelFactory

例如:

ChannelFactory<IMyContract> factory = new ChannelFactory<IMyContract>();
IMyContract proxy1 = factory.CreateChannel();
proxy1.MyMethod();

这样调用WCF服务有点无聊。

IMyContract proxy1 = null; 
try
{
    proxy1 = factory.CreateChannel();
    proxy1.MyMethod();
    ((ICommunicationObject)proxy1).Close();
}
catch
{
   ((ICommunicationObject)proxy1).Abort();
}

我们应该为每个代理调用重复这个代码片段吗?还是有一种通用的方法来创建一个包装类来关闭和中止代理?
编写像这样的类ServiceExecution.Execute(proxy=>proxy.MyMethod());是否是创建代理,并关闭或中止它的好方法?
4个回答

3

这里是一篇MSDN帖子,建议不要在.Net 3中使用生成的代理,因为它每次都会创建ChanelFactory,而在.Net 3.5中,ChanelFactory是被缓存的。

但是个人而言,我更喜欢自己使用ChanelFactory,即使使用了partials后,生成的代码仍然很痛苦。


2

第一种情况是当您使用VS添加服务引用时,它会为您生成所有代码,包括ServiceContrcats和DataContracts。

但是,当您使用ChannelFactory时,您必须已经在客户端上具有服务契约等内容。


我知道,但生成的数据契约不方便使用。假设我们有两个服务,第一个返回数据契约,应将其作为参数传递给第二个服务。在这种情况下,我们应该手动复制数据契约,因为数据契约存在于2个不同的命名空间中。 - Arsen Mkrtchyan
您仍然可以编辑由VS生成的代码。并且您可以拥有一个单独的DataContract。 - Incognito
任何服务更改和代理重新生成后,您的编辑将会丢失,不是吗? - Arsen Mkrtchyan

2

我建议采用第一种方法。

我发现了这个博客,其中包含源代码示例,还解释了如何正确处理连接(关闭、中止等)。该博客还包含了MSDN的更多详细信息链接。


1
这篇博客只是解释了第一种方法如何实现,但并没有提及与第二种方法相比的优点。 - Arsen Mkrtchyan
@ArsenMkrt:是的,你说得对。我在我的回答中添加了一个链接,提供了更多关于我建议的方法的信息。 :-) - Manfred

0
手动从运行中的服务创建服务代理可能是一个不错的选择。在添加服务引用时,Visual Studio 在幕后使用的工具是 svcutil。使用它,您可以在一个公共位置生成代理类,然后在每个需要的项目中链接到它,并且可以更好地控制代理类。
例如,要为名为 TestService 的服务在本地端口 8000 上生成代理,您可以在 Visual Studio 命令提示符中运行以下命令,在代理目录中生成代理类 TestServiceProxy.cs。
cd "C:\src\proxies"
svcutil /noLogo /out:TestServiceProxy http://localhost:8000/TestService

该工具还有一些其他有用的参数,例如:

添加 /n:*,WcfServices.TestService 将为代理类指定命名空间。

添加 /config:TestServiceProxy.config,svcutil 将生成一个使用 TestService 的示例配置文件,包括端点、绑定等。

添加 /r:"Common.dll",svcutil 生成的代理类将不会对服务使用但在 Common.dll 中定义的类型进行定义。

使用 svcutil /? 获取更多信息。


/config:它将生成一个名为output.config的默认配置文件。 - Rup
并非所有的业务情况都可以通过svcutil配置实现,例如,在不同的项目中生成数据契约、在不同的项目中生成服务契约和代理,这是否可能呢?我想是不可能的。 - Arsen Mkrtchyan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接