WCF從理論到實(shí)踐(16):操作重載(帶視頻+ppt+源碼)
如果您懶得看下面的文字,您按下面的提示下載視頻教程,里面還有ppt和源代碼
本文目的:
閱讀本文,您能了解以下知識(shí)
- 什么是操作重載?操作重載有什么好處
- WCF的服務(wù)端如何解決操作重載的問(wèn)題?
- WCF的客戶端如何解決操作重載問(wèn)題?
- 小結(jié)
什么是操作重載?操作重載有什么好處
重載指的是在同一個(gè)類,接口或者結(jié)構(gòu)中包含多個(gè)同名的 方法,而這些方法的參數(shù)列表或者返回值各不相同.使用它的好處在于提高模型的強(qiáng)壯性和通用性,使模型在一個(gè)可維護(hù)統(tǒng)一高度上運(yùn)行,其功能和返回依賴于傳遞的參數(shù). 在傳統(tǒng)的程序開(kāi)發(fā)中,我們程序員經(jīng)常使用這種技術(shù),比如一個(gè)有一個(gè)功能既能夠計(jì)算兩個(gè)整數(shù)的和,又能計(jì)算兩個(gè)雙精度數(shù)的和,這樣的需求,我們往往會(huì)按下面這樣書寫代碼:
public int Add(int a, int b) 
{ 
return a + b; 
} 
public double Add(double a, double b) 
{ 
return a + b; 
} 

而在WCF中,還能不能這么干呢?不能!為什么呢?WCF中無(wú)論是服務(wù)端還是客戶端,如果單拿出來(lái)一個(gè)都是支持操作重載的,但是客戶端代理生成的依據(jù)卻是WSDL,而WSDL是不支持操作重載的,另外客戶端調(diào)用服務(wù)端的一個(gè)操作的必須先要確定兩個(gè)要素:1)操作所屬的服務(wù)是哪一個(gè)?2) 操作在服務(wù)中的名稱是什么?這樣的話,向傳統(tǒng)應(yīng)用程序程序那樣重載就會(huì)出現(xiàn)問(wèn)題!
WCF的服務(wù)端如何解決操作重載的問(wèn)題?
如果按照下面的代碼來(lái)實(shí)現(xiàn)一個(gè)服務(wù):
服務(wù)契約
[ServiceContract] 
public interface IService 
{ 
[OperationContract] 
int Add(int a, int b); 

[OperationContract] 
double Add(double a, double b); 
} 

而服務(wù)實(shí)現(xiàn)為:
public class Service : IService 
{ 
public int Add(int a, int b) 
{ 
return a + b; 
} 
public double Add(double a, double b) 
{ 
return a + b; 
} 
} 

那么,在編譯的時(shí)候,是沒(méi)有錯(cuò)誤的。此時(shí),我們?cè)侔凑障旅娴拇a實(shí)現(xiàn)一個(gè)托管:
using(ServiceHost host = new ServiceHost(typeof(Service),new Uri("net.tcp://127.0.0.1:12345"))) 
{ 
NetTcpBinding bind = new NetTcpBinding(); 
host.AddServiceEndpoint(typeof(IService), bind, ""); 
//下面代碼的目的是添加一個(gè)MeatedataExchage的EndPoint 
BindingElement bindElement = new TcpTransportBindingElement(); 
CustomBinding metaBind = new CustomBinding(bindElement); 
ServiceMetadataBehavior metaBehavior = host.Description.Behaviors.Find<ServiceMetadataBehavior>(); 
if (metaBehavior == null) 
{ 
metaBehavior = new ServiceMetadataBehavior(); 
host.Description.Behaviors.Add(metaBehavior); 
} 
host.AddServiceEndpoint(typeof(IMetadataExchange), metaBind, "MEX"); 
host.Open(); 
Console.WriteLine("服務(wù)已經(jīng)運(yùn)行!"); 
Console.Read(); 
} 

隨后,我們啟動(dòng)托管程序,發(fā)現(xiàn)代碼在運(yùn)行到ServiceHost host = new ServiceHost(typeof(Service),new Uri("net.tcp://127.0.0.1:12345"))的時(shí)候,發(fā)生如下的異常:
這個(gè)異常提示我們,同一個(gè)協(xié)定之中不能存在相同的操作,在WCF中操作重載是不顯示適用的。而且問(wèn)題不在于編譯階段,而在于托管階段。
但是我們能通過(guò)一些改進(jìn)的手段來(lái)獲取WCF對(duì)操作重載的支持。我們先把服務(wù)契約的定義更改為如下的代碼:
[ServiceContract] 
public interface IService 
{ 
[OperationContract(Name="AddInt")] 
int Add(int a, int b); 

[OperationContract(Name="AddDouble")] 
double Add(double a, double b); 
} 

此時(shí),我們?cè)趩?dòng)托管,發(fā)現(xiàn)已經(jīng)能夠正常運(yùn)行了
到此,我們是不是就完美的解決了WCF中關(guān)于操作重載的問(wèn)題呢?不,還沒(méi)有,因?yàn)閃CF既包含服務(wù)端,又包含客戶端,我們當(dāng)前已經(jīng)將服務(wù)端順利的運(yùn)行起來(lái)了。總結(jié)一下,就說(shuō)服務(wù)端不是顯示支持重載的,重載的操作各自的別名必須更不一致。
WCF的客戶端如何解決操作重載問(wèn)題?
但客戶端呢?下面就來(lái)看下客戶端對(duì)操作重載的反應(yīng)。
要想實(shí)現(xiàn)客戶端,我們創(chuàng)建一個(gè)Console的客戶端應(yīng)用程序,然后需要用SvcUtiil.exe生成代理類,方法如下
打開(kāi)Proxy.cs,我們會(huì)發(fā)現(xiàn)代理的代碼如下:
仔細(xì)觀察代理的代碼不難發(fā)現(xiàn),代理中的服務(wù)契約以及服務(wù)實(shí)現(xiàn)的操作與服務(wù)端定義的想比,有所更改。而且對(duì)于代理類來(lái)說(shuō),已經(jīng)沒(méi)有了重載,雖然此代理類能夠被正常使用,但是卻沒(méi)有了重載的好處,如何更改代理類,才能使其也有重載是下面要研究的問(wèn)題。
我們將代理中的服務(wù)契約IService中的操作定義修改為:
[System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IService/AddInt", ReplyAction="http://tempuri.org/IService/AddIntResponse",Name="AddInt")] 
int Add(int a, int b);

[System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IService/AddDouble", ReplyAction="http://tempuri.org/IService/AddDoubleResponse",Name="AddDouble")] 
double Add(double a, double b); 

然后將服務(wù)實(shí)現(xiàn)ServiceClient中的方法更改為:
public int Add(int a, int b) 
{ 
return base.Channel.Add(a, b); 
}

public double Add(double a, double b) 
{ 
return base.Channel.Add(a, b); 
} 
創(chuàng)建一個(gè)Console的客戶端應(yīng)用程序,然后將修改后的Proxy.cs拷貝到其中,實(shí)現(xiàn)客戶端調(diào)用,代碼如下:
IService ws = new ServiceClient(new NetTcpBinding(), new EndpointAddress("net.tcp://127.0.0.1:12345")); 
using (ws as IDisposable) 
{ 
Console.WriteLine(ws.Add(1,2).ToString()); 
Console.WriteLine(ws.Add(1.3, 2.4).ToString()); 
} 
Console.Read(); 
將解決方案設(shè)置為多啟動(dòng)項(xiàng)目,并啟動(dòng)托管和客戶端,出現(xiàn)下面的結(jié)果:
說(shuō)明客戶端和服務(wù)端已經(jīng)成功通訊。從上面實(shí)現(xiàn)客戶端的方法來(lái)看,客戶端想實(shí)現(xiàn)重載,也必須保證重載操作的別名要有服務(wù)端的相匹配,其各不相同。
小結(jié)
從本文可以看出,WCF編程雖然保持了大部分原有編程模式,也繼承了原有模式足夠多好的做法,但是限于分布式開(kāi)發(fā)與傳統(tǒng)應(yīng)用程序的差異,在有些細(xì)節(jié)上還是有區(qū)別的,比如本文所討論的操作重載問(wèn)題,其實(shí)還有很多類似問(wèn)題,比如繼承的差異,序列化的差異,處理集合的差異等等。要想真正的掌握這些問(wèn)題,必須要深刻了解分布式開(kāi)發(fā)的特型。加深對(duì)服務(wù)交互,類型轉(zhuǎn)換,封送等WCF架構(gòu)方面的理解。以下幾點(diǎn)是對(duì)本文的總結(jié):
1) 對(duì)于WCF中的服務(wù)端,對(duì)服務(wù)契約和服務(wù)實(shí)現(xiàn)不支持顯示的操作重載,但可以通過(guò)設(shè)置重載操作的別名來(lái)改善這種狀況
2) 對(duì)于WCF客戶端,默認(rèn)情況下,生成的代理也不支持操作重載,想要改變這種狀況也必須依賴于別名。
3) 我推薦的做法是在服務(wù)端還是要用別名的方式支持操作重載,在客戶端手動(dòng)更改代理類,以便也支持操作重載。
視頻,課件以及源碼下載
出處:http://jillzhang.cnblogs.com/
本文版權(quán)歸作者和博客園共有,歡迎轉(zhuǎn)載,但未經(jīng)作者同意必須保留此段聲明,且在文章頁(yè)面明顯位置給出原文連接,否則保留追究法律責(zé)任的權(quán)利。

閱讀本文,您能了解以下知識(shí)
1) 什么是操作重載?操作重載有什么好處
2) WCF的服務(wù)端如何解決操作重載的問(wèn)題?
3) WCF的客戶端如何解決操作重載問(wèn)題?
4) 小結(jié)



浙公網(wǎng)安備 33010602011771號(hào)