WCF服務(wù)契約基本應(yīng)用技巧解讀
我們在應(yīng)用WCF服務(wù)契約的時候,需要掌握一些應(yīng)用技巧,才能幫助我們輕松的應(yīng)用這一功能來完成各種功能需求。在這里我們就一起來看看WCF服務(wù)契約的分解與設(shè)計方法,以方便大家理解。
C++與C#均支持操作的重載,但在WCF的編程模型中,卻并不支持這種技術(shù)。坦白說,在WCF的編程模型,對于面向?qū)ο蟮闹С侄际潜容^弱的,包括后面要介紹的繼承體系與多態(tài),都存在許多問題。因此,在服務(wù)端我們不能定義這樣的WCF服務(wù)契約:
- [ServiceContract]
- interface ICalculator
- {
- [OperationContract]
- int Add(int arg1,int arg2);
- [OperationContract]
- double Add(double arg1,double arg2);
- }
雖然在編譯時能夠通過,然而一旦在裝載宿主時,就會拋出InvalidOperationException異常。以ICalculator契約為例,WCF會認(rèn)為是零個操作。
解決的辦法是利用OperationContract特性的Name屬性,例如:
- [ServiceContract]
- interface ICalculator
- {
- [OperationContract(Name = "AddInt")]
- int Add(int arg1,int arg2);
- [OperationContract(Name = "AddDouble")]
- double Add(double arg1,double arg2);
- }
不過采用這種方式,存在的問題是生成的代理會將Name屬性指定的名稱作為代理操作的方法名。這對于編程者而言,并非好的方式。所幸我們可以手動對生成的代理進(jìn)行修改,將它修改為與WCF服務(wù)契約一致的操作名。由于,此時通過Name指定了操作的別名,因此,避免了裝載宿主拋出的異常。
契約的繼承
即使父接口標(biāo)記了[ServiceContract],子接口仍然需要標(biāo)記[ServiceContract],因為ServiceContractAttribute是不可繼承的。服務(wù)類對服務(wù)契約的實現(xiàn),與傳統(tǒng)的C#編程沒有什么區(qū)別。例如:
- [ServiceContract]
- interface ISimpleCalculator
- {
- [OperationContract]
- int Add(int arg1,int arg2);
- }
- [ServiceContract]
- interface IScientificCalculator : ISimpleCalculator
- {
- [OperationContract]
- int Multiply(int arg1,int arg2);
- }
- class MyCalculator : IScientificCalculator
- {
- public int Add(int arg1,int arg2) { return arg1 + arg2;
- }
- public int Multiply(int arg1,int arg2) { return arg1 * arg2;
- }
- }
公開終結(jié)點的時候,可以對***層的契約接口公開一個單獨(dú)的終結(jié)點:
- < service name=”MyCalculator”> < endpoint> < addressaddress=
”http://localhost:8001/MyCalculator/”> < bindingbinding=
”basicHttpBinding”> < contractcontract=” IScientificCalculator”>
< /endpoint> < /service>
客戶端在導(dǎo)入如上的WCF服務(wù)契約時,會取消服務(wù)契約的繼承層級,并利用OperationContract特性中的Action與ReplyAction屬性,保留原來定義每個操作的契約名。但為了使客戶端編程能夠與服務(wù)編程保持一致,***是恢復(fù)客戶端的契約層級。方法并無什么太玄妙的地方,無非就是根據(jù)服務(wù)契約層級對客戶端契約進(jìn)行手工修改。修改后的客戶端契約及其代理的定義如下:
- [ServiceContract]
- public interface ISimpleCalculator {
- [OperationContract]
- int Add(int arg1,int arg2);
- }
- public partial class SimpleCalculatorClient : ClientBase
< ISimpleCalculator>, ISimpleCalculator- {
- public int Add(int arg1,int arg2)
- {
- return Channel.Add(arg1,arg2);
- } //Rest of the proxy }
- [ServiceContract]
- public interface IScientificCalculator : ISimpleCalculator {
- [OperationContract]
- int Multiply(int arg1,int arg2);
- }
- public partial class ScientificCalculatorClient : ClientBase
< IScientificCalculator>,IScientificCalculator {- public int Add(int arg1,int arg2) {
- return Channel.Add(arg1,arg2); }
- public int Multiply(int arg1,int arg2) {
- return Channel.Multiply(arg1,arg2); }
- //Rest of the proxy }
在書中還提出了所謂的代理鏈(Proxy Chaining)技術(shù),實質(zhì)上就是使得分別實現(xiàn)不同層級接口的代理類形成一個IS-A的繼承關(guān)系。如上的定義,就可以使ScientificCalculatorClient繼承自SimpleCalculatorClient,而不是繼承ClientBase< IScientificCalculator>:
- public partial class SimpleCalculatorClient :
ClientBase< IScientificCalculator>, ISimpleCalculator {- public int Add(int arg1,int arg2) {
- return Channel.Add(arg1,arg2);
- } //Rest of the proxy }
- public class ScientificCalculatorClient : SimpleCalculatorClient,
IScientificCalculator {- public int Multiply(int arg1,int arg2) {
- return Channel.Multiply(arg1,arg2); } //Rest of the proxy }
只有這樣,如下代碼才是正確的:
- SimpleCalculatorClient proxy1 = new SimpleCalculatorClient( );
- SimpleCalculatorClient proxy2 = new ScientificCalculatorClient( );
- ScientificCalculatorClient proxy3 = new ScientificCalculatorClient( );
以上就是對WCF服務(wù)契約的相關(guān)介紹。
【編輯推薦】






