2010-08-19 74 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