调用过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. 创建一个版本库,把文件夹用Git管理起来

    创建一个文件夹,把这个文件夹用Git管理起来,那么这个文件夹的改变都可以被Git跟踪到,当然也可以将Git中的文件还原到某一个时刻. 首先创建一个空的目录,然后将空的目录由Git来管理 1.建立一个文 ...

  2. 在 Mac 安装Docker

    https://blog.csdn.net/jpiverson/article/details/50685817 https://legacy.gitbook.com/book/yeasy/docke ...

  3. JAVA:形参与实参

    今天百度startWith函数的用法,无意中看到了形参这个称呼,因此就去了解了下形参与实参. 在传值机制中,其实就是把变量b(实参)的地址传递给了形参(也就是实参跟形参都是用的同一个地址,在传值之前形 ...

  4. Blender 插件整理

    系统自带插件列表: 好用的第三方插件: Align Vertices to Grease Pencil, 对齐顶点到蜡笔,   https://blenderartists.org/t/addon-a ...

  5. 【HDOJ4109】【拓扑OR差分约束求关键路径】

    http://acm.hdu.edu.cn/showproblem.php?pid=4109 Instrction Arrangement Time Limit: 2000/1000 MS (Java ...

  6. ACM-ICPC 2018 北京赛区网络预赛(9.22)

    #include<bits/stdc++.h> using namespace std; ; *maxn]; *maxn]; *maxn]; int main() { int T; sca ...

  7. hdu3338 Kakuro Extension 最大流

    If you solved problem like this, forget it.Because you need to use a completely different algorithm ...

  8. 通过阻止 touchstart 事件,解决移动端的 BUG

    在 iOS10 下,即使设置了 meta 标签的 user-scalable=no 依然不能阻止用户缩放. 解决此 BUG 的方法是阻止 PC 事件: document.addEventListene ...

  9. python猜数字(多种实现方法)

    设定一个理想数字比如:66,让用户输入数字,如果比66⼤,则显示猜测的结果⼤了:如果比66⼩,则显示猜测的结果小了;只有等于66,显示猜测结果 第一种方式(最简单的方式实现) n = 66 # 理想数 ...

  10. day21-22Redis Mahout

    PS: Redis 在博客的 JavaEE PS:大数据实时执行3个特性,Storm,kafka,Redis PS:比如在系统中,1s中有大量的请求涌入的系统中,那么请求就存入数据库就挂了,这就需要到 ...