zoukankan      html  css  js  c++  java
  • WCF类型共享技巧【转载】

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


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

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

    image

    这个方法缺点很明显,它只有在客户端和服务端在同一个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文件:

    image

    找到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!

  • 相关阅读:
    Docker手动搭建sentry错误日志系统
    Flask源码解析:Flask应用执行流程及原理
    django Rest Framework---缓存通过drf-extensions扩展来实现
    Python实现 -- 冒泡排序、选择排序、插入排序
    Python查找算法之 -- 列表查找和二分查找
    java设计模式之单例模式
    中文乱码解决方案
    web应用中Filter过滤器之开发应用
    web应用中的Filter过滤器之基础概述
    会话跟踪技术
  • 原文地址:https://www.cnblogs.com/baozhu/p/5030913.html
Copyright © 2011-2022 走看看