调用过WCF服务的同学可能都会遇到这样的问题,同一个实体类型,不同的服务Visual Studio生成了不同的版本,例如Service1.User和Service2.User,对于C#来说,这是两个不同的类型,Service1获得的User是放不到Service2服务里去的。手动的属性赋值来转换显然是不可取的,所以就共享类型了。

方法1,服务端和客户端共享数据契约程序集。

这个方法最常用,也是大家最熟悉的方法,把WCF的数据契约放在一个独立类库里,服务端,客户端都引用这个程序集,然后在生成WCF时,选择重新使用引用程序集中的类型即可。

这个方法缺点很明显,它只有在客户端和服务端在同一个Visual Studio解决方案内才方便,否则要不断手动更新数据契约程序集。更不用说是第三方的服务。

方法二,暴力转换类型

这个其实不是类型共享,不过也是解决这个问题的一种手段。就是借助AutoMapperEmitMapper这样的类库帮助快速转换类型。下面是一个例子。

Money类型包含User实体和Currency枚举和一个数字的Amount,Money的定义

[DataContract(Namespace = Consts.Namespace)]
 public class Money 
{     
	[DataMember]
         public decimal Amount { get; set; }
        [DataMember]     
    	 public Currency Currency { get; set; } 
        [DataMember]
         public UserInfo User { get; set; } 
}

Currency:

[DataContract(Namespace = Consts.Namespace)]
 public enum Currency 
{     
	[EnumMember]
	Euro, 
        [EnumMember]
	Usd, 
	[EnumMember]
        PoundSterling
 }

UserInfo:

[DataContract(Namespace = Consts.Namespace)]
 public class UserInfo 
{     
	[DataMember]
	public string FirstName { get; set; } 
	[DataMember]     
	public string LastName { get; set; }     
	[DataMember]     
	public string Email { get; set; }     
	[DataMember]     
	public string Phone { get; set; }     
	[DataMember]     
	public string Id { get; set; }
 }

对于DepositServiceNoSharp和WithdrawalServiceNoSharp这两个WCF服务版本的Money和User,可以这样添加一些扩展方法

using AutoMapper;
using DepositService = Client.DepositServiceNoSharp;
using Client.WithdrawalServiceNoSharp;
 namespace Client {     
	public static class Extensions     
	{         
		static Extensions()         
		{             
			Mapper.CreateMap<DepositService.Money, Money>();             
			Mapper.CreateMap<Money, DepositService.Money>();             
			Mapper.CreateMap<DepositService.UserInfo, UserInfo>();             
			Mapper.CreateMap<UserInfo, DepositService.UserInfo>();         
		}
        public static Money ToWithdrawal(this DepositService.Money money)
        {             
		return Mapper.Map<DepositService.Money, Money>(money);         
        public static DepositService.Money ToDeposit(this Money money)         
	{             
		return Mapper.Map<Money, DepositService.Money>(money);
	}     
}

然后就可以轻松转换

var money = new Money {
		Amount = 1,     
		Currency = Currency.Usd,     
		User = new UserInfo     {         
				Email = "zhww@outlook.com",         
				FirstName = "zhang",         
				Id = "123",         
				LastName = "weiwen",         
				Phone = "110"     
}; 
var depositMoney = money.ToDeposit();

方法三,使用SvcMap实现类型共享

其实这个才是文章的重点,前面可以忽略。

生成第一个WCF服务后,点击”显示所有文件“去编辑SvcMap文件:

找到MetadataSources节点,原来只有一个,现在把其他要引用的服务添加到这里,例如:

  <MetadataSources>     
	<MetadataSource Address="http://localhost:34875/DepositService.svc" Protocol="http" SourceId="1" />     
	<MetadataSource Address="http://localhost:34875/WithdrawalService.svc" Protocol="http" SourceId="2" />   
</MetadataSources> 

再右击服务,”更新服务引用“,所有服务都会生成到同一个命名空间里,实现类型共享。

最后感谢原作者,原文链接

还有顺道向微软出示一下中指,把这个功能隐藏得这么深。

The End!

WCF类型共享技巧【转载】的更多相关文章

  1. [转]WCF类型共享技巧

    调用过WCF服务的同学可能都会遇到这样的问题,同一个实体类型,不同的服务Visual Studio生成了不同的版本,例如Service1.User和Service2.User,对于C#来说,这是两个不 ...

  2. WCF服务编程中使用SvcMap实现类型共享等技巧【转】

    原文链接:http://www.cr173.com/html/19026_1.html 国外的一篇文章:Sharing DataContracts between WCF Services 文中提到的 ...

  3. WCF技术剖析之三十:一个很有用的WCF调用编程技巧[下篇]

    原文:WCF技术剖析之三十:一个很有用的WCF调用编程技巧[下篇] 在<上篇>中,我通过使用Delegate的方式解决了服务调用过程中的异常处理以及对服务代理的关闭.对于<WCF技术 ...

  4. WCF技术剖析之三十:一个很有用的WCF调用编程技巧[上篇]

    原文:WCF技术剖析之三十:一个很有用的WCF调用编程技巧[上篇] 在进行基于会话信道的WCF服务调用中,由于受到并发信道数量的限制,我们需要及时的关闭信道:当遇到某些异常,我们需要强行中止(Abor ...

  5. Linux使用笔记: 使用Samba访问windows的共享目录(转载)

    转自:http://easwy.com/blog/archives/mount-a-windows-shared-folder-on-linux-with-samba/ 通常我们使用Samba都是在W ...

  6. 常用MIME类型(Flv,Mp4的mime类型设置)(转载)

    转载地址:http://www.cuplayer.com/player/Help/2011/0625/83.html 也许你会在纳闷,为什么我上传了flv或MP4文件到服务器,可输入正确地址通过htt ...

  7. GJM : Unity3D - UI - UI边缘流光特效小技巧 [转载]

    感谢您的阅读.喜欢的.有用的就请大哥大嫂们高抬贵手"推荐一下"吧!你的精神支持是博主强大的写作动力以及转载收藏动力.欢迎转载! 版权声明:本文原创发表于 [请点击连接前往] ,未经 ...

  8. 创建和导出SVG的技巧(转载)

    本文转载自: 创建和导出SVG的技巧

  9. TextBox使用技巧--转载

    [转载出处注明:http://tieba.baidu.com/p/3677706825] 在使用Visual Basic开发应用程序时,TextBox控件是最常用的(特别对于数据库程序),以下是笔者在 ...

随机推荐

  1. 终极C语言指针

    // ex1.cpp : Defines the entry point for the console application. // #include "stdafx.h" # ...

  2. Win2003可用序列号(标准版与企业版)

    通用性好的win2003序列号: (推荐先用这个里面的)FJ8DH-TQPYG-9KFHQ-88CB2-Y7V3Y GRD4P-FTQQF-JCDM8-4P6JK-PFG7M JD7JX-KCDTH- ...

  3. mac os x lipo 工具

    lipo是管理Fat文件的工具,可以查看平台列表,提取.重新打包 dreamdeMac-mini:test dream$ lipo -info libtest001.a Architectures i ...

  4. 非原创。使用ajax加载控件

    非原创.来自博客园老赵. public class ViewManager<T> where T : System.Web.UI.UserControl { private System. ...

  5. [LeetCode&Python] Problem 226. Invert Binary Tree

    Invert a binary tree. Example: Input: 4 / \ 2 7 / \ / \ 1 3 6 9 Output: 4 / \ 7 2 / \ / \ 9 6 3 1 Tr ...

  6. 20155208徐子涵Vim编辑器学习经验

    20155208徐子涵 2016-2017-2 Vim编辑器学习经验 当我们运用虚拟机进行书写代码时,我们就会用到Vim编辑器,用Vim编辑器进行编辑特别方便,而Vim编辑器中也有一些操作需要去学习. ...

  7. 集合框架 ArrayList LinkedList(待续)

    ArrayList中存储的元素的内存空间是连续的, LinkedList内存空间不是连续的 集合对象不能被序列化到硬盘中 http://blog.csdn.net/eson_15/article/de ...

  8. 【shell编程】之基础知识-输入/输出和重定向

    大多数 UNIX 系统命令从你的终端接受输入并将所产生的输出发送回​​到您的终端.一个命令通常从一个叫标准输入的地方读取输入,默认情况下,这恰好是你的终端.同样,一个命令通常将其输出写入到标准输出,默 ...

  9. shell-url-decode

    查询每个小时的clk ,然后获取对应的字段 #!/bin/bash urldecode(){ echo -e "$(sed 's/+/ /g;s/%\(..\)/\\x\1/g;')&quo ...

  10. adx-desc-adtype统计

    数据分析脚本: filepath="request.log.2017-12-01-15" File.open("#{filepath}").each do |l ...