在咱們看來,Service Orientation提供了一種對業務、功能進行分解的方式。針對SO,咱們把一個具體的業務流程或者一個複雜的功能分解成一個個獨立完成某項任務的子單元,這些子單元經過一個個Service來承載。對於Service自己來說,他們應該是自治的,獨自完成本身的功能、不依賴於其餘的Service。可是Service的價值體如今它被潛在的消費者使用的程度。這實際上包含兩方面的內容,做爲Service自己,它如何將本身暴露出來,供一切可能的潛在用戶調用,這些潛在用戶不只僅指那些不一樣的Client,也包含其餘的Service:Service Orientation其中一個特徵就是「Service should be composite」,鼓勵將一個個相關細粒度的Service組合成一個大的Service。這樣有利於較大限度的實現重用,而重用每每意味着更小的投入、更佳的可維護性。而另外一方面就是這些消費者經過怎樣的方式來調用它所須要的Service。 html
這實際上體現了二者相互交互的問題。在一個分佈式的環境中要實現二者的交互,有兩個必需要解決的問題:如何保證Service的使用者對Service的調用可以被Service端理解,以及對Service的調用如何抵達Service Side。後者實質上是關於communication的問題,咱們如今不去談它。第一個問題就是Contract須要解決的問題。 網絡
咱們知道SOA一個主要的目標就是促進不一樣技術平臺的互操做,要真正實現這樣一個宏偉的目標是一件極不容易的事情,須要不一樣的廠商和標準組織相互協做,制定一個你們一致遵循的標準。這樣一個標準就是WS-* 。咱們很清楚,不管個個廠商各自的標準怎樣千差萬別,可是有個標準是他們必需要遵循的,那就是Internet的標準,若是哪家公司拒絕Internet,那確定要被淘汰的。而對於Internet,基於Http的網絡協議和基於XML的數據表達已經成爲了事實上的標準。對於SOA來講,XML不只僅用於表示Service調用攜帶的數據(參數和返回值),更用於表示這個調用自己,以及知足各類要求的控制信息, 好比基於Security、Session、Reliable Messaging、Transaction等等的控制信息。WS-*就是一個基於XML的標準。而對於SOA中的Contract所要作的就是尋求一種廠商中立的方式來表示Service的接口、和用於交互的數據結構。前者就是Service Contract、後者就是Data Contract。 數據結構
SOA中的一個Service由一組相關的Operation來構成。Service Contract用於表示構成該Service全部Operation的Interface(而不是Implementation)。說得更加具體點,你們都知道Consumer和Service之間的交互都是經過Message的形式來實現的,一次交互就是一次Message Exchange。在不一樣的場景,咱們以不經過Pattern來進程Message Exchange,好比咱們一般使用Request-Response的方式來向Service發送Request進而獲得返回結果,咱們也能夠以Request-Forget的形式來異步地調用Service(不須要從Service獲取Response),咱們可讓一個Service在沒有收到任何Request的狀況下,以廣播的形式向註冊的Client發送通知,固然咱們還有其餘不一樣的消息交互的模式,咱們把這些不一樣的信息交互方式稱爲MEP(Message Exchange Pattern)。也就是說,一個Operation最終經過被最終轉換成了按照某種MEP進行的消息交互,而Service Contract旨在實現對這種MEP的描述,好比是否須要Request Message或者Response Message(若是僅僅有Response Message就是Notification的方式;若是僅僅具備Request Message,那就是咱們上面談到的Request-Forget的模式),和Message自己具備的格式。 app
上面咱們說了Service Contract是以一種廠商中立的形式描述體現爲某種模式的消極交互、構成整個Service的全部Operation。而咱們也說了Consumer和Service的交互本質上看就是按照某種Pattern體現的一次Message Exchange,好像具備了Service Contract的描述就能夠了。可是實際上,單單有了Service Contract對Service的描述還不夠,由於Service Contract自己缺少對攜帶於Message,用於信息傳遞的數據類型的描述,而這是Data Contract須要解決的問題。咱們知道不一樣的技術平臺對數據類型的表示是不同的,可能某一種技術平臺使用16bit來表述一個浮點數,另外一種則使用32bit。因此要想實現不一樣技術平臺的互操做,將不一樣技術平臺同一類型的數據以一種廠商中立的形式來描述是必須的。 異步
歸納的說,SOA中的Service Contract和Data Contract就是一種廠商中立的數據呈現方式對Service Interface和Data Type的。而Service的調用都是經過SOAP Message來實現,SOAP是基於XML,而對於XML結構的定義,咱們很天然地想到XSD,咱們可簡單地將SOA中的Contract當作是一個XSD。
Contract in WCF 分佈式
上面咱們其實是在一個廠商中立的前提下探討Contract,這裏的Contract和具體的平臺和技術無關。接下來咱們要談的是基於技術的話題:討論一下WCF下的Contract。簡單地說,WCF中的Contract主要的功能就是如何將一個基於.NET的CLR Type,Interface或者Class,轉化成一個咱們上面提到的Neutral Contract。好比,若是咱們在一個Interface和它的成員上分別運用Service Contract Attribute和Operation Contract,當咱們Host實現了該Interface的Service的時候,WCF就能將在一個.NET-specific的CLR Type暴露成一個Neutral Service Contract。同理對於一個,咱們經過在一個Class和它的成員上分別添加DataContractAttribute和DataMemberAttribute,就能夠就該CLR Type轉變成Neutral Data Contract。 ide
好比咱們一個運用了DataContractAttribute和DataMemberAttribute的Order class: ui
就能夠轉變成另外一種廠商中立的、以XSD表示的Neutral Data Contract:
this
當Client須要調用該Order type的Service的時候,在本地須要一個Data Type可以匹配上面的以XSD體現的Data Contract。通常地,咱們能夠在VS中經過Add Service Reference的方式或者經過一些Tools,好比XSDUtil和SvcUtil來生成這樣的Class。好比咱們經過Add Service Reference方式,就能夠生成下面一個對應的Order class: spa
經過上面這樣一個在Client自動生成的Order class,你就能夠建立Order對象來調用相應的Service了。這種自動生成代碼的方式確實很省事,並且當Service端的Data Contract改變的時候,你只須要Update Service Reference就能夠從新生成並覆蓋現有的代碼。可是,就我我的來講,我不要喜歡使用這樣的方式,若是對Service暴露出來的數據結構很熟悉的話,我寧願本身編寫這樣的class。特別地,對於WCF-WCF(Client和Service都是WCF),若是可能的話,讓定義Contract的Assembly在Service和contract共享,我想是最直接的方式。
上面咱們說所說的都是根據Service暴露出來的、以廠商中立方式體現的(好比XSD)Client端生成或者自行建立與之相對的Data type。可是對於下面這樣的場景,重建Data Type卻不是一個好的選擇:Client如今已經有一個Order class,並且不少的業務邏輯均依賴於這個class,如今須要調用一個現有的Order Processing Service對Order做某種處理,可是Service 的Order Type,說得更準確地,Service暴露出來的Order Data Contract和Client現有的Order class不太一致,很顯然在這種狀況下,Client端部可能使用本地Order對象來調用該Service,由於Client提供的數據不符合該Data Contract,若是想上面講到了從新生成或者建立一個新的Order class,就意味着其餘依賴於現有Order class的業務邏輯均會受其影響。因此,在這裏,咱們須要WCF Data Contract提供給咱們的另外一種功能——適配功能:經過現有的CLR Type上添加或者改變DataContractAttribute 或者DataMemberAttribute的參數來使現有的CLR Type符合一個既定的Data Contract。究其本質,不管將CLR Type暴露成一個Neutral Contract也好,將CLR Type與既定的Neutral Contract進行適配也罷,這兩種功能都是等效的。
接下來,咱們就根據一個例子來討論WCF Data Contract如何將一個現有的CLR Type與一個既定的Neutral Data Contract匹配。
Data Contract Mapping Mechanism
經過上面的介紹,咱們發現WCF Data Contract就如同一個適配器,彌合了 CLR Type和Neutral Contract的差別,很容易地實現了他們之間的匹配。接下來,咱們就以一個實際的例子來介紹WCF DataContract的這種適配功能:經過DataContractAttribute的修飾,實現了將一個現有Data Type向一個既定的Neutral Data Contract進行適配,從而實現了對基於該Neutral Data Contract的Service 進行正常調用的目的。
咱們就以上面提到的Order Class爲例,Service端的Order class最終暴露成一個以XSD表示的Neutral Contract:
Order class:
XSD:
設咱們在Client有一個與之結構類似的CustomOrder class:
仔細分析CustomOrder和Service的Order以及XSD,咱們發現二者除告終構同樣以外,沒有一處使相同的,具體體如今:
若是咱們如今要使咱們的CustomOrder知足現有的Order Data Contract,咱們就須要消除這些不一樣之處,經過DataContractAttribute和DataMemberAttribute,這樣的問題根本就不是問題,下面就是咱們從新定義的CustomOrder class。
經過在DataContractAttribute指定Name和Namespace使Data Contract和Namespace和既定的Contract相匹配,經過DataMemberAttribute的Name和Order參數是成員的名稱和次序與既定的Contract相匹配。
[原創]談談WCF中的Data Contract(1):Data Contract Overview
[原創]談談WCF中的Data Contract(2):WCF Data Contract對Generic的支持
[原創]談談WCF中的Data Contract(3):WCF Data Contract對Collection & Dictionary的支持
[原創]談談WCF中的Data Contract(4):WCF Data Contract Versioning