2010-08-19 32 views
0

我有三個WCF服務(.svc),它們爲SOAP消息生成.wsdl引用。WCF版本控制:更新屬性名稱空間和支持Previous命名空間

鑑於該命名空間的一部分需要,DataContract屬性,更改所有的ServiceContract,OperationContract的例如

[DataContract(Namespace = "http://old.com.au/types/")] 

[DataContract(Namespace = "http://new.com.au/types/")] 

它怎麼說,我還是能爲客戶提供支持其有舊的服務引用(沒有他們需要更新,因爲他們可能沒有時間立即更新),並允許客戶端獲得新的服務引用來獲得新的名稱空間?沒有任何服務正在改變,只是命名空間。

到目前爲止,我已經讀了很多的東西,但下面的文章表明,它是可以從ServiceHostFactory更改服務類型:http://blog.ranamauro.com/2008/07/hosting-wcf-service-on-iis-site-with_25.html

這意味着創造的每兩份合同(把儘可能多的儘可能在一個地方實現),並在運行時找出要使用的服務類型。這會在我的場景中造成一些混亂。

問:是否有另一種方法可以完成此任務,或者是否應該完成此類任務,並且客戶端要更新到新的名稱空間。

(如果有來自客戶機的命名空間不匹配我的錯誤:用行動消息「...」不能在接收器進行處理,由於ContractFilter不匹配)

回答

3

IMO,您需要爲舊客戶提供舊服務(最好是)老客戶端,並在新終端點提供新服務。當所有舊客戶端遷移到新版本時,您可以取出舊服務。 也許,你可以使用繼承來減少你的努力,例如

[DataContract(OldNameSpace)] 
ClassA { 
... 
} 

[DataContract(NewNameSpace)] 
ClassB : ClassA { 
} 

同樣,從一個新的繼承創建新的服務合同。服務實施不需要改變,希望實施新的合同。現在您必須配置兩個終點 - 一個用於舊合同,另一個用於新合同。

編輯:將樣品接口和實現

比方說,您老合同是像

public interface IOldContract 
{ 
    ClassA GetFoo(); 
    void DoBar(ClassA a); 
} 

現在你可以選擇新的合同既可以作爲

public interface INewContract 
{ 
    ClassB GetFoo(); 
    void DoBar(ClassB b); 
    ClassB GetMix(ClassB a); 
} 

public interface INewContract2 : IOldContract 
{ 
    ClassB GetFoo2(); 
    void DoBar2(ClassB b); 
    ClassB GetMix2(ClassB b); 
} 

我傾向於隨着後期的變化(因爲新合同與舊合同保持兼容)。但就你而言,你可以選擇前者,因爲無論如何你都會暴露兩個端點。 現在,您需要修改服務實現如下:

public class ServiceImplementation : INewContract2 
{ 
    #region INewContract2 Members 

    public ClassB GetFoo2() 
    { 
     // Your old implementation goes here 
    } 

    public void DoBar2(ClassB b) 
    { 
     DoBar(b); 
    } 

    public ClassB GetMix2(ClassB b) 
    { 
     return GetMixHelper(b); 
    } 

    #endregion 

    #region IOldContract Members 

    public ClassA GetFoo() 
    { 
     return GetFoo2(); 
    } 

    public void DoBar(ClassA a) 
    { 
     // You old implementation goes here 
    } 


    public ClassA GetMix(ClassA a) 
    { 
     return GetMixHelper(a); 
    } 

    #endregion 

    private ClassB GetMixHelper(ClassA a) 
    { 
     // Your old implementation goes here 
    } 

} 

我希望你的想法。即使在這裏,你也有多種代碼組織的選擇。您可以擁有兩個骨架服務實現類 - 一個用於舊合同,另一個用於新合同。兩者都會將實際的功能委託給助手類(這是您當前的實現)。

+0

謝謝你會試用 – CRice 2010-08-19 07:06:22

+0

+1我也會採取這種方法。 – 2010-08-19 07:41:19

+0

有一個問題,如果我有每個datacontract 2比我需要在許多實現中翻倍...舊服務返回一個ClassA我現在需要一個新的serivce和方法,它返回一個ClassB但它是相同的如果我想分享現有功能的一部分,我必須映射返回ClassA作爲ClassB的內部方法的返回類型。 – CRice 2010-08-20 00:46:57