zoukankan      html  css  js  c++  java
  • WCF 开发日志 WCF契约设计

    一、摘要

            

              由于公司需要使用WCF进行分布式开发,刚刚可以借用这个时候学学WCF了,随便在博客上记录下在项目中用到WCF的那些功能写的内容可能不全但是都是在项目中能用的实用的WCF功能点和技术。

             下面引用网络上一长图片具体在那里看到的已经忘记了。

              %E5%9B%9E%E9%A1%BE 

              下面引用网络上的一段话来描述这个图:        

                在宿主进程嵌入了一个或者多个服务,服务通过EndPoint也就是端点对外进行暴露,在客户端进程如果想获取宿主进程当中的服务,需要一个Proxy也就是代理,客户端进程如果说现在需要获取宿主进程当中的某一个服务的话,客户端把要求提交给代理,然后通过代理封装到EndPoint当中,再通过Message也就是消息的方式传到宿主进程当中的EndPoint,在提交到Service当中去处理,处理完毕在经过一个反向的过程。

    二、本文大纲

         

           a、摘要  。

           b、WCF契约设计 -- 契约知识 。

           c、WCF契约设计 -- 契约示例 。

           d、WCF契约设计 -- 契约总结。

           e、WCF契约设计 -- 目前还没有用的。

     
    三、WCF契约设计 -- 契约知识

          

    在WCF当中服务契约是通过属性的方式来定义的,也就是我们希望在服务这一端暴露服务给客户端,我们可以在这些服务上面我们通过添加ServiceContract和OperationContract这样的属性,在以前我们开发WebService的时候要想给外界暴露一些Web方法的话需要添加WebMethod标记,ServiceContract和OperationContract的添加和WebMethod的添加是类似的效果
     

       面向对象设计原则OO:

     

    <1>单一职责原则(SRP): 一个类应当仅有一个引起它变更的原因。

      <2>开放封闭原则(OCP): 类模块应当是可扩大的,然则不成批改(对扩大开放,对更改封闭)。

      <3>Liskov 调换原则(LSP): 子类必须可以或许调换它们的基类。

      <4> 依附倒置原则(DIP): 高层模块不该该依附于低层模块,二者都应当依附于抽象。 抽象不该该依附于实现细节,实现细节应当依附于抽象。

      <5>接口隔离原则(ISP): 不该该强迫客户法度依附于它们不消的办法。

       接口时辰即遵守单一职责和接口隔离等原则,又要推敲体系的开辟本钱。公道的接口是专业的、松耦合的、规矩化和可重用的接口

    接口分发原则

          [ServiceContract] (接口或类的设计应该征询OOP)

     
    应用于接口或者类中
    建议应用于接口中
        消除服务实现的耦合性
        服务可能会实现多于1个契约
    总是提供有意义的命名空间
    能够显式地指定Name
     image 
    如:
    [ServiceContract(Name = "HeatingManagerService",  
    Namespace= "http://www.cnblogs.com/luomingui")]    
    public interface IHeatingManagerBase    { ....... } 

    [OperationContract](方法的设计)

    服务契约中的所有方法都应该拥有 OperationContract
    能够显式地指定 Name , Action , ReplyAction
     image 

    如:

     [OperationContract(Name = "AddHouseHoldInfo", Action = "http://www.cnblogs.com/luomingui/AddHouseHoldInfo",  ReplyAction = "http://www.cnblogs.com/luomingui/AddHouseHoldInfoResponse")]      
      bool AddHouseHoldInfo(RequestHeader request, HouseHoldInfoEntity model);   

       [DataMember] (实体类的设计)

    实体类中所有的字段都应该拥有DataMember
    能够显式指定 Name , IsRequired , Order
    image 
    如:
    [DataMember(Name = "AreaId", IsRequired = false, Order = 0)]
    public Guid AreaId{ get;  set; }
    [DataMember(Name = "Id", IsRequired = false, Order = 1)]
    public Guid Id{ get;  set; } 
     
        [DataContract] (实体类的设计) 
        只有声明为DataContract的类型的对象可以被传送,且只有成员属性会被传递,成员方法不会被传递。
     image 
    如:
    [System.Runtime.Serialization.DataContract(Namespace = "http://schemas.thatindigogirl.com/samples/2006/06")]
    public class DeviceHCV03HisInfoEntity : BaseClass<DeviceHCV03HisInfoEntity>
    {.....}
     
    四、WCF契约设计 -- 契约示例

    已知类型在服务契约中使用多态的行为'

    在服务操作中暴露基本类型将已知类型相关到(基本类型,特定操作,整个服务契约)

    采用属性声明或者配置的方式来实现想我们常用的实体类就是

    KnownType

    image

    已知类型契约(KnownTypesContract)  示例:

     1:  [ServiceContract]
     2:  public interface IService1
     3:  {
     4:      [OperationContract]
     5:      [ServiceKnownType(typeof(SexBoy))]//通过接口文件方法中添加 SexType 标ê记实现多态。        
     6:      void GetSex(SexType sex);
     7:  }
     8:   
     9:  public class Service1 : IService1
    10:  {
    11:      public void GetSex(SexType sex)
    12:      {
    13:          string strSex = "";
    14:          switch (sex)
    15:          {
    16:              case SexType.boy:
    17:                  strSex = "男";
    18:                  break;
    19:              case SexType.girl:
    20:                  strSex = "女";
    21:                  break;
    22:          }
    23:      }
    24:  }
    33:  
    34:  [DataContract]
    35:  [KnownType(typeof(SexBoy))]//通过基类添加 KnowType 标记实现多态
    36:  public class UserInfoEntity
    37:  {
    38:      [DataMember(Name = "IdContract", IsRequired = false, Order = 0)]
    39:      public string Id
    40:      {
    41:          get;
    42:          set;
    43:      }
    44:      [DataMember(Name = "NameContract", IsRequired = false, Order = 1)]
    45:      public string Name
    46:      {
    47:          get;
    48:          set;
    49:      }
    50:      [DataMember(Name = "SexContract", IsRequired = false, Order = 2)]
    51:      public virtual SexType Sex
    52:      {
    53:          get;
    54:          set;
    55:      }
    56:   
    57:  }
    58:   
    59:  [DataContract]
    60:  public class SexBoy : UserInfoEntity
    61:  {
    62:      public SexBoy()
    63:      {
    64:   
    65:      }
    66:   
    67:      [DataMember(Name = "SexCategories", IsRequired = true, Order = 3)]
    68:      public override SexType Sex
    69:      {
    70:          get { return SexType.boy; }
    71:      }
    72:   
    73:  }
    74:   
    75:  [DataContract]
    76:  public enum SexType
    77:  {
    78:      [EnumMember]
    79:      boy = 0,
    80:      [EnumMember]
    81:      girl = 1,
    82:  }
    83:   
    消息契约(MessageContract) 
    image  
      • MessageContractAttribute        
     – 对控制消息头和消息体元素提供了强力支持       
    • 所支持的属性:         
    – MessageHeaderAttribute         
    – MessageBodyMemberAttribute        
     – 凡是有[MessageHeader]或[MessageBody]的那些属性,它们就是在客户端调用服务相应方法的参数。      
     • 用于:         
    – 添加自定义头(custom headers)         
    – 控制消息是否被包装         
    – 控制签名与加密       [MessageContract]:         
    • 将一个类型转换为SOAP消息         
    – 类型可以包含消息头和消息体的元素         
    • 能够设置IsWrapped, ProtectionLevel         
    • 可以设置显式Name, Namespace         
    如下面的代码:         
    [MessageContract(IsWrapped=true, ProtectionLevel=ProtectionLevel.Sign)]         
    public class SaveLinkRequest         {…}         
    [MessageContract]         public class SaveLinkResponse         {…}        
    [MessageHeader]:         
    • 应用到消息契约的域(fields)或者(         properties)        
     – 为创建自定义头提供了简单的方法        
     • 能够提供Name, Namespace, ProtectionLevel        
     • 可以设置SOAP协议的设置:Relay, Actor,MustUnderstand         
    [MessageBody]:        
     • 应用到消息契约的域(fields)或者属性(properties)        
     • 能够拥有多个body元素         
    – 等价于在操作中拥有多个参数         
    – 返回多个复杂类型数据的唯一方法        
     • 总是提供顺序(Order)         
    • 可以设置Name, Namespace, ProtectionLevel
     1:      [ServiceContract(ProtectionLevel = ProtectionLevel.EncryptAndSign)]
     2:      public interface IService2
     3:      {
     4:          [OperationContract]
     5:          SaveResponse SaveItem(SaveRequest requestMessage);
     6:          [OperationContract]
     7:          GetResponse GetItem(GetRequest requestMessage);
     8:      }
     9:   
    10:      public class Service2 : IService2
    11:      {
    12:          private UserInfoEntity _item;
    13:   
    14:          public SaveResponse SaveItem(SaveRequest requestMessage)
    15:          {
    16:              this._item = requestMessage.Item;
    17:              return new SaveResponse();
    18:          }
    19:   
    20:          public GetResponse GetItem(GetRequest requestMessage)
    21:          {
    22:              if (requestMessage.LicenseKey != "lmg")
    23:              {
    24:                  throw new FaultException("Invalid license key.");
    25:              }
    26:              _item.Id = "001";
    27:              _item.Name = "lmg";
    28:              _item.Sex = SexType.boy;
    29:   
    30:              return new GetResponse(_item);
    31:          }
    32:      }
    33:   
    34:      #region 消息契约
    35:      [MessageContract(IsWrapped = true, ProtectionLevel = ProtectionLevel.EncryptAndSign)]
    36:      public class SaveRequest
    37:      {
    38:          [MessageBodyMember]
    39:          public UserInfoEntity Item { get; set; }
    40:      }
    41:   
    42:      [MessageContract(IsWrapped = false)]
    43:      public class SaveResponse
    44:      {
    45:      }
    46:   
    47:      [MessageContract(IsWrapped = false)]
    48:      public class GetRequest
    49:      {
    50:          [MessageHeader]
    51:          public string LicenseKey { get; set; }
    52:      }
    53:   
    54:      [MessageContract(IsWrapped = false)]
    55:      public class GetResponse
    56:      {
    57:          public GetResponse()
    58:          {
    59:          }
    60:   
    61:          public GetResponse(UserInfoEntity item)
    62:          {
    63:              this.Item = item;
    64:          }
    65:   
    66:          [MessageBodyMember]
    67:          public UserInfoEntity Item { get; set; }
    68:      }
    69:      #endregion
    70:  

    消息契约注意:

           image

           配置文件注意的地方 权限应为 Message

    image 
    五、WCF契约设计 -- 契约总结
    服务契约定义可用的操作和签名
    数据契约和其他可序列化的类型能够包含在服务契约中
    已知类型,允许多态契约
    三、WCF契约设计 -- 资料  

    MSDN

    http://social.msdn.microsoft.com/Forums/zh-CN/wcfzhchs/thread/4c483f01-2e59-4b67-9426-10e9746d0b93

  • 相关阅读:
    扯一下关于魔兽改键的蛋
    Emacs23.3在ubuntu10.10下的手动编译与安装
    GRUB2英文文档的部分翻译
    WinForm中Crossthread operation not valid错误的解决方法
    C# 嵌入式资源
    raster配准
    excel vba 玫瑰图 风速 风向
    使用UserControl好处
    How does ArcSDE use Oracle Spatial? arcsde怎么使用oracle spatial
    信息抽取的定义(definition of information extraction)
  • 原文地址:https://www.cnblogs.com/luomingui/p/2653413.html
Copyright © 2011-2022 走看看