好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

WCF类型共享技巧

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/

    

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

版权信息

查看更多关于WCF类型共享技巧的详细内容...

  阅读:42次