如何在同一个WCF服务中命名多个版本化的ServiceContracts?

时间:2010-03-26 17:38:49

标签: visual-studio wcf web-services namespaces versioning

当您必须在ServiceContract中引入重大更改时,最佳做法是保留旧的更改并创建新的更改,并在命名空间中使用某个版本标识符。

如果我理解正确,我应该能够做到以下几点:

[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吗?

1 个答案:

答案 0 :(得分:4)

通常,您不会拥有同时实现旧界面和新界面的服务实现。因此,如果新客户端出现并连接到您的新服务,它只会获得新界面,一切都很好。

如果你需要能够提供两种接口,那么是 - 你需要做一些“魔术”才能实现这一目标:

  • 如果可以的话,从旧的派生新界面。只要您只添加新内容,这就有效。然后,新的服务实现将实现旧式接口以及新的

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

    因此,您的服务实现将同时具有WriteGreetingWriteNewGreeting方法 - 新客户端可以连接并使用其中任何一个,而较旧的客户端仍会看到其IVersionService1接口和“旧的“命名空间,因此能够继续呼叫您的服务

  • 如果您无法从旧服务派生新服务,请创建一个全新服务,并在新端点上公开它,例如一个新的地址或端口。这样,现有的客户端可以继续调用现有的和众所周知的服务,而新的服务可以被定向到单独的端点上的单独服务,对他们来说也应该没问题