[WCF 4.0新特性] 标准终结点与无(.SVC)文件服务激活
今天介紹WCF 4.0的另外兩個(gè)新特性:標(biāo)準(zhǔn)終結(jié)點(diǎn)(Standard Endpoint)和無(.SVC)文件服務(wù)激活(File-Less Activation)。前者實(shí)現(xiàn)了針對典型通信場景對終結(jié)點(diǎn)的定制,后者讓你在進(jìn)行IIS/WAS的服務(wù)寄宿中無須定義.svc文件。
一、標(biāo)準(zhǔn)終結(jié)點(diǎn)
我們知道,綁定的本質(zhì)就是一系列相關(guān)綁定元素的有序集合,而系統(tǒng)綁定就是基于若干典型的通信場景對相關(guān)綁定元素的整合。WCF通過系統(tǒng)綁定對綁定元素進(jìn)行了定制,那么能否在終結(jié)點(diǎn)級別對組成該終結(jié)點(diǎn)的ABC(地址、綁定和契約)也進(jìn)行相應(yīng)的定制呢?實(shí)際上這對于最新版本的WCF是可行的,我們將這個(gè)機(jī)制稱為“標(biāo)準(zhǔn)終結(jié)點(diǎn)”。
所謂標(biāo)準(zhǔn)終結(jié)點(diǎn),就是針對典型的通信場景選擇組成終結(jié)點(diǎn)的要素(主要是綁定和契約)進(jìn)而創(chuàng)建出一個(gè)標(biāo)準(zhǔn)的終結(jié)點(diǎn)。在使用的時(shí)候,如果你需要的終結(jié)點(diǎn)要素和標(biāo)準(zhǔn)終結(jié)點(diǎn)完全一致,就無需進(jìn)行重復(fù)的設(shè)置;如果不一致,則只需要單獨(dú)對此進(jìn)行重新設(shè)置以覆蓋定義在標(biāo)準(zhǔn)終結(jié)點(diǎn)的默認(rèn)設(shè)置。
比如說,對于用于發(fā)布元數(shù)據(jù)的終結(jié)點(diǎn)總是將IMetadataExchange作為其契約,并且在大部分情況下使用MexHttpBinding。如果我們基于這兩個(gè)元素創(chuàng)建一個(gè)標(biāo)準(zhǔn)的MexEndpoint,那么在為服務(wù)配置發(fā)布元數(shù)據(jù)的終結(jié)點(diǎn)的時(shí)候就只需要指定地址就可以了。實(shí)際上,WCF確實(shí)為我們創(chuàng)建了這么一個(gè)標(biāo)準(zhǔn)的MexEndpoint終結(jié)點(diǎn)。包含MexEndpoint終結(jié)點(diǎn)在內(nèi),WCF總共為我們定義了如下面的列表所示的9個(gè)標(biāo)準(zhǔn)終結(jié)點(diǎn)。
- mexEndpoint:用于公開服務(wù)元數(shù)據(jù)的標(biāo)準(zhǔn)終結(jié)點(diǎn);
- dynamicEndpoint:使用 WS-Discovery 在運(yùn)行時(shí)動態(tài)查找終結(jié)點(diǎn)地址的標(biāo)準(zhǔn)終結(jié)點(diǎn);
- discoveryEndpoint:由服務(wù)用于發(fā)送發(fā)現(xiàn)消息的標(biāo)準(zhǔn)終結(jié)點(diǎn);
- udpDiscoveryEndpoint:通過 UDP 多播綁定為發(fā)現(xiàn)操作預(yù)配的標(biāo)準(zhǔn)終結(jié)點(diǎn);
- announcementEndpoint:由服務(wù)用于發(fā)送公告消息的標(biāo)準(zhǔn)終結(jié)點(diǎn);
- udpAnnouncementEndpoint:由服務(wù)用于通過 UDP 綁定發(fā)送公告消息的標(biāo)準(zhǔn)終結(jié)點(diǎn);
- workflowControlEndpoint:可用于對工作流實(shí)例調(diào)用控制操作的標(biāo)準(zhǔn)終結(jié)點(diǎn);
- webHttpEndpoint:帶有自動添加 WebHttpBehavior行為的WebHttpBinding綁定的標(biāo)準(zhǔn)終結(jié)點(diǎn);
- webScriptEndpoint:帶有自動添加 WebScriptEnablingBehavior行為的WebHttpBinding綁定的標(biāo)準(zhǔn)終結(jié)點(diǎn)。
如果你希望直接為某個(gè)服務(wù)配置一個(gè)標(biāo)準(zhǔn)終結(jié)點(diǎn),可以借助于WCF4.0為終結(jié)點(diǎn)的配置節(jié)添加的一個(gè)新的配置屬性kind,該屬性表示標(biāo)準(zhǔn)終結(jié)點(diǎn)名稱。在上面的配置中,我為服務(wù)配置了一個(gè)標(biāo)準(zhǔn)終結(jié)點(diǎn)mexEndpoint以實(shí)現(xiàn)基于MEX終結(jié)點(diǎn)形式的元數(shù)據(jù)發(fā)布。
1: <?xml version="1.0"?> 2: <configuration> 3: <system.serviceModel> 4: ... 5: <services> 6: <service name="Artech.WcfServices.Service.CalculatorService" > 7: <host> 8: <baseAddresses> 9: <add baseAddress="http://127.0.0.1:3721/calculatorservice"/> 10: </baseAddresses> 11: </host> 12: <endpoint binding="ws2007HttpBinding" contract="Artech.WcfServices.Contract.ICalculator" /> 13: <endpoint kind="mexEndpoint" address="mex"/> 14: </service> 15: </services> 16: </system.serviceModel> 17: </configuration>對于系統(tǒng)綁定來說,WCF允許你通過配置的方式對其進(jìn)行定制,標(biāo)準(zhǔn)終結(jié)點(diǎn)也不例外。如果標(biāo)準(zhǔn)的終結(jié)點(diǎn)默認(rèn)配置不能滿足你的要求,你可以在配置中對其進(jìn)行相應(yīng)的定制。在WCF配置節(jié)下添加了一個(gè)新的子結(jié)點(diǎn)<standardEndpoints>,用于對這9個(gè)標(biāo)準(zhǔn)終結(jié)點(diǎn)進(jìn)行定制。和自定義綁定一樣,你需要為自定義的標(biāo)準(zhǔn)終結(jié)點(diǎn)起一個(gè)名字。如果某個(gè)終結(jié)點(diǎn)需要使用到自定義的標(biāo)準(zhǔn)終結(jié)點(diǎn),標(biāo)準(zhǔn)終結(jié)點(diǎn)的名稱需要設(shè)置到終結(jié)點(diǎn)配置節(jié)的另一個(gè)額外的配置屬性endpointConfiguration上。
在下面的配置中,我們自定義了一個(gè)基于WS-Discovery 1.1的udpDiscoveryEndpoint,并起名為“wsd11”。而這個(gè)標(biāo)準(zhǔn)終結(jié)點(diǎn)通過終結(jié)點(diǎn)配置節(jié)的兩個(gè)屬性kind(kind="udpDiscoveryEndpoint")和endpointConfiguration(endpointConfiguration="wsd11")被添加到寄宿的CalculatorService服務(wù)的終結(jié)點(diǎn)列表中。
1: <?xml version="1.0"?> 2: <configuration> 3: <system.serviceModel> 4: <services> 5: <service name="Artech.WcfServices.Service.CalculatorService" > 6: <endpoint address="http://127.0.0.1:3721/calculatorservice" binding="ws2007HttpBinding" contract="Artech.WcfServices.Contract.ICalculator" /> 7: <endpoint kind="udpDiscoveryEndpoint" endpointConfiguration="wsd11"/> 8: </service> 9: </services> 10: <standardEndpoints> 11: <udpDiscoveryEndpoint> 12: <standardEndpoint name="wsd11" discoveryVersion="WSDiscovery11"/> 13: </udpDiscoveryEndpoint> 14: </standardEndpoints> 15: </system.serviceModel> 16: ... 17: </configuration>二、無.svc文件服務(wù)激活
我們都知道,在采用IIS/WAS進(jìn)行服務(wù)寄宿的情況下,我們需要為寄宿的服務(wù)創(chuàng)建一個(gè).svc文件。在通常的情況下(當(dāng)然你也可以以內(nèi)聯(lián)的形式將整個(gè)服務(wù)類型也定義其中),我們僅僅在該.svc文件中定義基本的<%@ServiceHost%>指令信息。其中最重要的指令信息自然是通過Service屬性指定的寄宿服務(wù)的類型(實(shí)際上調(diào)用ServiceHostFactory的CreateServieHost方法傳入的第一個(gè)參數(shù)值)。如果采用自定義ServiceHost,我們還需要定義用于創(chuàng)建ServiceHost的ServiceHostFactory的類型(通過Factory屬性)。
在《通過自定義ServiceHost實(shí)現(xiàn)對WCF的擴(kuò)展[實(shí)例篇]》中,我們介紹了如何通過自定義ServiceHost的方式實(shí)現(xiàn)WCF與Unity這個(gè)IoC框架進(jìn)行集成。我們?yōu)榇藙?chuàng)建了自定義的ServiceHost(UnityServiceHost)和相應(yīng)的ServiceHostFactory(UnityServiceHostFactory)。下面就是采用了UnityServiceHostFactory這個(gè)自定義ServiceHostFactory創(chuàng)建的.svc的內(nèi)容。
1: <%@ ServiceHost Service="Artech.WcfServices.Servicies.ResourceService: defaultContainer" 2: Factory="Artech.WcfExtensions.IoC.UnityServiceHostFactory, Artech.WcfExtensions"%>從消息交換的角度來說,客戶端對IIS/WAS寄宿下服務(wù)的調(diào)用本質(zhì)上體現(xiàn)在對.svc這個(gè)真實(shí)存在的物理文件的訪問。如果服務(wù)尚未激活,WCF最終根據(jù)讀取請求的物理文件來激活相應(yīng)的服務(wù)。具體來說,就是獲取用于創(chuàng)建ServiceHost的ServiceHostFactory的類型(如果沒有通過<%@ServiceHost%>指令的Factory進(jìn)行顯式設(shè)置,默認(rèn)使用的ServiceHostFactory的類型為System.ServiceModel.Activation.ServiceHostFactory)。在正確解析出ServiceHostFactory類型之后,通過反射創(chuàng)建用于寄宿服務(wù)的ServiceHost對象。
如果WCF的服務(wù)端能夠根據(jù)請求正確地創(chuàng)建出基于目標(biāo)服務(wù)的ServiceHost,就能解決服務(wù)的激活問題。進(jìn)一步來說,如果服務(wù)端能夠維護(hù)一個(gè)Service/ServiceHostFactory與請求地址之間的映射關(guān)系,我們就可以不再需要.svc文件,因?yàn)?svc對于服務(wù)激活來說就是起到了這么一個(gè)映射的作用。在最新的WCF中,這么一個(gè)映射關(guān)系可以在配置文件中進(jìn)行設(shè)置。換言之,如果在配置對這個(gè)映射關(guān)系進(jìn)行了相應(yīng)設(shè)置之后,我們將不再需要為服務(wù)定義了.svc文件了。
在<system.serviceModel>/<serviceHostingEnvironment>配置節(jié)下,具有一個(gè)<serviceActivations>子節(jié)點(diǎn)。上述的關(guān)于Service/ServiceHostFactory與請求地址之間的映射關(guān)系就定義在這個(gè)配置節(jié)點(diǎn)下。具體來說,<serviceActivations>配置節(jié)下的配置元素具有三個(gè)基本的屬性,其中service和factory對用著原來定義在.svc文件中<%@ServiceHost>指令的Service和Factory屬性,而relativeAddress則表示服務(wù)相對服務(wù)寄宿的IIS站點(diǎn)的地址,該地址必須以.svc為后綴。下面一段配置與上面給出的.svc文件具有相同的作用,有了這段配置,.svc就不再需要了。
1: <?xml version="1.0" encoding="utf-8" ?> 2: <configuration> 3: <system.serviceModel> 4: ... 5: <serviceHostingEnvironment> 6: <serviceActivations> 7: <add relativeAddress="ResourceService.svc" 8: service="Artech.WcfServices.Servicies.ResourceService: defaultContainer" 9: factory="Artech.WcfExtensions.IoC.UnityServiceHostFactory, Artech.WcfExtensions"/> 10: </serviceActivations> 11: </serviceHostingEnvironment> 12: </system.serviceModel> 13: </configuration>再舉個(gè)例子,如何我們需要通過IIS的方式來寄宿我們熟悉的CalculatorService,在不需要定義.svc的情況下,下面的XML片斷代表了所需的最少配置。借助于默認(rèn)終結(jié)點(diǎn)(《[WCF 4.0新特性] 默認(rèn)終結(jié)點(diǎn)》)的自動添加機(jī)制,WCF會為寄宿服務(wù)實(shí)現(xiàn)的每個(gè)服務(wù)契約針對于每一個(gè)基地址添加一個(gè)終結(jié)點(diǎn)。由于通過配置屬性relativeAddress定義的地址就是服務(wù)的相對基地址,所以基于這個(gè)地址的終結(jié)點(diǎn)回自動添加。
1: <?xml version="1.0" encoding="utf-8" ?> 2: <configuration> 3: <system.serviceModel> 4: <serviceHostingEnvironment> 5: <serviceActivations> 6: <add service="Artech.WcfServices.Service.CalculatorService" relativeAddress="OrderService.svc"/> 7: </serviceActivations> 8: </serviceHostingEnvironment> 9: </system.serviceModel> 10: </configuration>?
附上剛剛收到的9個(gè)新版新浪微博邀請碼,有興趣的朋友可以體驗(yàn)一下:
http://weibo.com/upcode/dgPcW4Gd7
http://weibo.com/upcode/dgPWOkRM9
http://weibo.com/upcode/dgPSQxHsz
http://weibo.com/upcode/dgPPBYReT
http://weibo.com/upcode/dgPPqPvgP
http://weibo.com/upcode/dgPGhy18k
http://weibo.com/upcode/dgPBEOB1M
http://weibo.com/upcode/dgPuEwykK
http://weibo.com/upcode/dgPt72DV0
轉(zhuǎn)載于:https://www.cnblogs.com/artech/archive/2011/09/20/standardendpoint.html
總結(jié)
以上是生活随笔為你收集整理的[WCF 4.0新特性] 标准终结点与无(.SVC)文件服务激活的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 敏捷开发用户故事系列之二:如何面向客户价
- 下一篇: 单链表的快速排序(转)