最近在做项目的时候,发现同一个数据契约再客户端隶属于两个不同的命名空间,为此如果两个服务进行交互的时候会涉及到类型 的问题,互操作性很差,要进行不必要的拆和装,在前面终于让我找到了答案,下面我来描述一下这个场景,大家请看下面
[实体类] 大家请注意命名空间
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.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.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.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下一个版本可以改进这一点!!
文章到此结束,如有不对,请大家指出,谢谢
我的博客:www.garychen.net