2010-02-23 61 views
1

舊版本的WCF的是根據老版本的界面合同發現在WCF後服務合同的繼承

<endpoint name="ServiceName" address="http://production.server/Service.svc" 
binding="basicHttpBinding" bindingConfiguration="myBasicHttpBinding" 
contract="myAPI.IOriginalService" /> 

與新版本提供

<endpoint name="ServiceName" address="http://development.server/Service.svc" 
binding="basicHttpBinding" bindingConfiguration="myBasicHttpBinding" 
contract="myAPI.IDerivedService" /> 

這工作正常交付。舊客戶端可以通過詢問IOriginalService連接到任一服務器,而新客戶端可以請求IDerivedService ...但他們只能向開發服務器詢問,如果他們詢問生產服務器,則會引發錯誤。這很好。

我寧願讓新客戶試圖有點聰明,儘管他們可以使用新格式,但如果它不可用,則使用舊格式。我可以抓住這個例外,但這很昂貴,我寧願做一個測試,也不願意發現已知的可能結果。

因此,我想連接到端點並詢問合同值,然後使用返回值來決定要請求的類型,例如,

var endPoint = someMethod("ServiceName"); 
var contractName = endPoint.WhatContractDoYouOffer(); 
if(contractName == "IOriginalService") 
    CallAMethod<IOriginalService>(parameters); 
else 
    CallAMethod<IDerivedService>(newParameters); 

這可行嗎?

回答

0

有內WCF沒有「開箱即用」,以支持該功能 - 除了可能:

  • 暴露在一個端點
  • 舊的服務合同上的獨立,新的端點公開新服務(新地址,新端口 - 無論如何)

但做出決定在哪裏連接需要做客戶端。

你可能會想到一個「調度員」WCF服務,你可以問哪裏去找哪個合同 - 但是至少這個WCF服務的端點和合同必須在所有時間都保持固定。

當然,你可以在你的客戶端的app.config多個端點 - 那些可以被加載到內存中,並檢查:

ClientSection cs = ConfigurationManager.GetSection("system.serviceModel/client") as ClientSection; 

if(cs != null) 
{ 
    foreach (ChannelEndpointElement ep in clientSection.Endpoints) 
    { 
     if(ep.Contract == 'IMyService') 
     { 
      Uri endpointAddress = e.Address; 
     } 
    } 
} 

有了這個,你可以創建一個單一的客戶端配置,其包含所有端點,並且您可以動態地找到您感興趣的端點。