WCF类型共享技巧
调用过WCF服务的同学可能都会遇到这样的问题,同一个实体类型,不同的服务Visual Studio生成了不同的版本,例如Service1.User和Service2.User,对于C#来说,这是两个不同的类型,Service1获得的User是放不到Service2服务里去的。手动的属性赋值来转换显然是不可取的,所以就共享类型了。
方法1,服务端和客户端共享数据契约程序集。这个方法最常用,也是大家最熟悉的方法,把WCF的数据契约放在一个独立类库里,服务端,客户端都引用这个程序集,然后在生成WCF时,选择重新使用引用程序集中的类型即可。
这个方法缺点很明显,它只有在客户端和服务端在同一个Visual Studio解决方案内才方便,否则要不断手动更新数据契约程序集。更不用说是第三方的服务。
方法二,暴力转换类型这个其实不是类型共享,不过也是解决这个问题的一种手段。就是借助 AutoMapper , EmitMapper 这样的类库帮助快速转换类型。下面是一个例子。
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!
作者: Leo_wl
出处: http://www.cnblogs.com/Leo_wl/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
版权信息