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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM