2010-03-26 53 views
4

當您必須在ServiceContract中引入重大更改時,最佳做法是保留舊的更改並創建一個新的更改,並在命名空間中使用某些版本標識。如何在同一個WCF服務中爲多個版本化的ServiceContracts命名?

如果我理解正確這,我應該能夠做到以下幾點:

[ServiceContract(Namespace = "http://foo.com/2010/01/14")] 
public interface IVersionedService 
{ 
    [OperationContract] 
    string WriteGreeting(Person person); 
} 

[ServiceContract(Name = "IVersionedService", Namespace = "http://foo.com/2010/02/21")] 
public interface IVersionedService2 
{ 
    [OperationContract(Name = "WriteGreeting")] 
    Greeting WriteGreeting2(Person2 person); 
} 

有了這個,我可以創建支持兩個版本的服務。這實際上起作用,從soapUI測試時它看起來很好。

但是,當我使用「添加服務引用」在Visual Studio中創建客戶端時,VS會忽略名稱空間,只會看到兩個具有相同名稱的接口。爲了區分它們,VS爲其中一個名稱添加「1」。我結束了代理稱爲

ServiceReference.VersionedServiceClient 

ServiceReference.VersionedService1Client 

現在是不容易的,任何人看到這是較新的版本。

我應該給接口使用不同的名字嗎? E.g

IVersionedService1 
IVersionedService2 

IVersionedService/2010/01/14 
IVersionedService/2010/02/21 

這難道不是打敗命名空間的目的是什麼?

我應該將它們放在不同的服務類中,併爲每個版本獲取唯一的URL嗎?

回答

4

那麼,通常情況下,你不會有一個同時實現舊界面和新界面的服務實現。因此,如果新客戶端出現並連接到您的新服務,它只會獲得新界面,並且一切正常。

如果您需要能夠提供了兩個接口,然後是 - 你需要做一些「神奇」來實現這一目標:

  • 如果可以的話,從舊派生新界面。只要你只是添加新的東西,這就行得通了。然後,新的服務實現將實現兩個舊風格的界面,以及新的

    public interface IVersionedService2 : IVersionService1 
    { 
        [OperationContract(Name = "WriteNewGreeting")] 
        Greeting WriteNewGreeting(Person2 person); 
    } 
    

    所以,你的服務實現將不得不既WriteGreeting以及一個WriteNewGreeting方法 - 新的客戶端可以連接到和也可以使用,而老客戶仍然可以看到他們的IVersionService1接口和「舊」名稱空間,因此能夠繼續致電您的服務

  • 如果您不能從舊的派生新服務,創建一個全新的服務,並將其展示在新的端點上,例如一個新的地址或端口。這樣一來,現有的客戶可以繼續調用現有的和衆所周知的服務,而新的可以被定向到一個單獨的服務上一個單獨的終結點,事情應該罰款對他們來說,太

+0

感謝。我實際上不必從舊的接口中派生出新的接口來實現這兩個接口。我的服務確實是 public class VersionedService:IVersionedService,IVersionedService2 它工作正常。我的問題更多的是,當我已經使用版本化的XML命名空間時,是否必須向接口添加遞增的數字?你的回答似乎意味着我必須這樣做。 – 2010-03-27 06:43:46

+0

@Tor:不,不一定。如果你在兩個單獨的XML命名空間中有相同的接口 - 新舊接口,並在兩個單獨的端點(兩個URL)上公開 - 那麼客戶端將總是選擇一個或另一個,並且它不會在命名中發生任何衝突,認爲。 – 2010-03-27 09:28:11