2010-01-26 94 views
10

我有多个共享某些数据协定并需要使用svcutil.exe生成客户端代码的WCF服务。我遇到了两个最明显的方法来做到这一点,并需要一些帮助。如何为共享类型的多个WCF服务生成客户端代码

但首先,这里的服务:

[ServiceContract(Namespace = "http://www.me.com/services/")] 
public interface IFooService { 
    [OperationContract] 
    Response RunFoo(Request request); 
} 
[ServiceContract(Namespace = "http://www.me.com/services/")] 
public interface IBarService { 
    [OperationContract] 
    Response RunBar(Request request); 
} 

响应和请求是在​​一个单独的程序定义:

[DataContract(Namespace = "http://www.me.com/shared/")] 
public class Request { 
    [DataMember] 
    public int Input { get; set; } 
} 
[DataContract(Namespace = "http://www.me.com/shared/")] 
public class Response { 
    [DataMember] 
    public int Result { get; set; } 
} 

的服务在一些琐碎的方式来实现,编译,出版 - 让我们现在切换到客户端。

包括SvcUtil工具命令行这两种服务 - 这样的:

svcutil /o:Client.cs http://hostname.com/FooService.svc http://hostname.com/BarService.svc 

将导致大约重复数据类型众多的错误消息,从

Error: There was a validation error on a schema generated during export: Source: Line: 1 Column: 9087 Validation Error: The global element ' http://schemas.microsoft.com/2003/10/Serialization/:anyType ' has already been declared.

Error: There was a validation error on a schema generated during export: Source: Line: 1 Column: 12817 Validation Error: The complexType ' http://www.me.com/shared/:Response ' has already been declared.

结束

为每项服务单独生成一个客户端文件避免š这些错误:

svcutil /o:Foo.cs http://hostname.com/FooService.svc 
svcutil /o:Bar.cs http://hostname.com/BarService.svc 

但随后共享类型(如请求和响应)的定义将在Foo.cs然后在Bar.cs被复制,在编译器错误明显得到。

那么,什么是生成客户端代码消费这种服务的传统方式

限制:

  • 不能船舶包含共享类型的客户端(使他们能够使用svcutil.exe的的/ r选项)
  • 不能使用“添加服务引用...”命令汇编在Visual Studio中 - 需要一个svcutil命令行(或另一个命令行工具)。

回答

5

好了,基本上就可以

  • 要么把你的共享类型到一个单独的组件生成的客户端代码(您已经解雇是不可能的)

或然后在客户端可以使用:

  • 您必须分别为服务生成每个代理,并且每个服务都将获得自己的“请求”和“响应”类的“副本”

要么你可以共享共同的组件 - 或者你不能 - 我没有看到任何其他的选择,真的。

+0

但它不是一个二者或情况。通过在命令行中指定多个端点为svcutil,您可以生成一组输出文件,以在多个服务中重复使用DTO。无需从服务端重新使用程序集,也不需要每个服务都拥有自己的相同对象的副本。 – Bevan 2010-11-29 22:20:36

4

既然你已经排除了一个共享的DTO组件(为什么,顺便说一句?),在这种情况下最简单的选项看起来是产生在不同的C#的命名空间的类型(即两次调用svcutil),和映射两者之间的数据。从根本上说:将两种服务中的DTO视为巧合相似。

你可以使用像automapper这样的东西来减少工作量,或者你可以直接从A类序列化并反序列化到B类型(假设实际的数据数据等是相同的)。

+0

服务器端和客户端是在不同的组织。所以,我必须向每个客户端伸出手,并为他们提供DLL或将其转换为可下载或开源产品。无论如何,这将涉及更多的人,并且比开发人员仅仅选择正确的命令行选项组合更困难和昂贵的决定。 – azheglov 2010-01-26 20:35:53

0

当您运行客户端实用程序后,您将获得XXXXService.cs和output.config文件。

如果您观察到XXXXService类,则您拥有文件中的所有内容。您可以将它们拆分为单独的IXXXService和XXXService文件以及datacontracts文件。

然后你可以运行第二服务的效用,并添加IXXXService1.cs和1XXXService.cs文件和相同的datacontracts你可以用它来共享这些2.

我不知道这是否可以回答你题。我有an example可以帮助你。 您可以看到一些与MVC和WCF相关的更多示例here

2

如果您还没有找到解决方案,WSCF Blue可能会让您更接近解决方案。

http://wscfblue.codeplex.com/

它可以产生不同的文件中的每个类型,并覆盖上后续操作。

相关问题