谈WCF数据契约疑问之共享数据契约


最近在做项目的时候,发现同一个数据契约再客户端隶属于两个不同的命名空间,为此如果两个服务进行交互的时候会涉及到类型 的问题,互操作性很差,要进行不必要的拆和装,在前面终于让我找到了答案,下面我来描述一下这个场景,大家请看下面。

  [实体类]  大家请注意命名空间

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace GaryChenWCFService
{
  /// <summary>
  /// 测试实体类
  /// </summary>
  public class Customer
  {
    public string Name
    {
      get;
      set;
    }
    public string Sex
    {
      get;
      set;
    }
  }
}

  下面是1号服务  注意:返回的是GaryChenWCFService.Customer类型的对象

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace GaryChenWCFService.ServiceClasses
{
  public class OneCustomerService :ServiceContracts.IOneCustomer
  {
    #region IOneCustomer 成员
    public GaryChenWCFService.Customer GetCustomer()
    {
     //省略
    }
    #endregion

  下面是2号服务  注意:添加的是GaryChenWCFService.Customer类型的对象

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace GaryChenWCFService.ServiceClasses
{
  public class TwoCustomerService : ServiceContracts.ITwoCustomer
  {
    #region ITwoCustomer 成员
    public void AddCustomer( GaryChenWCFService.Customer cs )
    {
      //省略
    }
    #endregion
  }
}

宿主部分我们省略...我们来看客户端,问题来了

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace GaryChenClient
{
  class Program
  {
    static void Main( string[] args )
    {
     OneCustomerService_Proxy.OneCustomerClient OneService_Proxy = new GaryChenClient.OneCustomerService_Proxy.OneCustomerClient();
     TwoCustomerService_Proxy.TwoCustomerClient TwoService_Proxy = new GaryChenClient.TwoCustomerService_Proxy.TwoCustomerClient();
     OneCustomerService_Proxy.Customer cu = OneService_Proxy.GetCustomer();
     TwoService_Proxy.AddCustomer(cu);
    }
  }
}

  1号服务取得的Customer属于OneCustomerService命名空间,现在我要把这个取得出来的对象放入2号服务去进行处理,

  这就出现了同一个数据契约两个不同的命名空间问题,大家看一下对象浏览器两个代理所生成的东西,

  这样一来我们如果要放进2号服务去操作的话必须显示声明TwoCustomerService_Proxy.Customer进行转换,这样的场景

或许大家都经常碰到,下面我说一下解决办法,

  按照WCF编程第二版中的说法,我把原话给大家发一下

  在Visual Studio 2008添加一个服务引用时,你必须为每个服务引用提供唯一的新命名空间。导入的类型会定义在这个新的命名空间中。如果为共享了相同数据契约的两个不同服务添加引用,就会出现问题,因为你得到了两个不同的类型,在两个不同的命名空间,表示的却是相同的数据契约。然而,默认情况下,如果被客户端引用的任意一个程序集包含的数据契约,与已经暴露在引用服务元数据的数据契约类型匹配,Visual Studio 2008就不会再次导入。需要再次强调的是,已有的数据契约引用必须是在另一个引用程序集中,而不是在客户端项目自身。这一限制会在未来的Visual Studio版本中提供,而目前最方便的弥补措施与最佳实践则为:将所有共享的数据契约分解到指定的类库中,并让所有的客户端引用该程序集。然后,通过服务引用的高级设置对话框(参见图1-10),可以控制和配置引用程序集(如果存在)与有关的共享数据契约进行协调。“Reuse types in referenced assemblies”检查框默认是被选中的,但如果你需要也可以关闭这一功能。顾名思义,你只能共享数据契约,却不能共享服务契约。使用里面的单选按钮,可以让Visual Studio 2008跨所有的引用程序集重用数据契约,或者通过选择列表项限制对特定程序集的共享。

  s这段话的意思就是让你把我服务端的DLL引用到客户端来,在服务配置中来共享同一个数据契约,见下图

  大家看见没有,需要指定服务引用的程序集,这样才不会存在命名空间类型的问题,这样做我知道非常不合理,但是如果客户端自

  己开发的话而不是其他平台调用的话这样也是没有办法中的办法,期待WCF下一个版本可以改进这一点!!


« 
» 
快速导航

Copyright © 2016 phpStudy | 豫ICP备2021030365号-3