在单个客户端,多服务器环境中使用什么合同版本策略

时间:2011-10-28 10:43:30

标签: .net wcf versioning

我在网上读过一些关于版本化WCF合同的文章。这是一对夫妇:
WCF Versioning Guidelines
MSDN: Versioning Strategies

现在,我有点了解合同版本控制的基础知识,但所有这些文章(当然)主要是针对性的环境,其中有一台服务器和许多客户端,客户端可能比服务器旧。

在我的情况下,反过来说,一个客户端和许多服务器。这是因为我有一个应用服务器(客户端)可以与多个工作站(即wcf服务器)通信的环境。 客户端将始终具有最新版本,服务器可能具有旧版本。

我计划在同一服务中实现一个单独的服务(或者只是一个GetVersion方法)来获取服务器支持的版本,并根据它在客户端中选择正确的合同并进行真正的服务调用。 / p>

现在问题是,在这种情况下是否使用了松散版本,或者我应该使用严格的版本。

1 个答案:

答案 0 :(得分:0)

所以你正在做'服务器推送'?即您的固定IP硬件是否充当客户端,动态IP机器正在运行ServiceHosts?

我真的希望有一个“智能层”可以简单地放置在这里处理版本控制 - 但实际上没有灵丹妙药。 IExtensibleObject实际上只是维护往返的数据,但如果服务器只有旧的契约,那么它也只有旧的实现,所以它不能“使用”这个'扩展'信息。 / p>

您可以遵循几种做法。主要区别在于,更改版本号,或者不...在WCF合同的情况下,没有版本号,但版本编码到合同名称空间/ URI。

如果你不改变名称空间,那么你基本上就是说,“我将拥有一项服务,永远不会破坏向后兼容性(对于X版本)”。然后,您必须实施严格的开发实践,以确保不修改或删除任何方法,只能添加。这将阻止客户端发送服务器不再理解的请求。

另一种方法是使用合同的每个修订来更改WCF合同URI /名称空间。然后,您'server'将实现您想要支持的EACH版本的合同。例如,如果您支持3个先前版本的客户,则他们可能正在运行最新的WCF服务器,但WCF客户端不得超过3个版本,否则WCF服务器将无法理解该请求(因为URI /合同)命名空间不存在)。 这通常是我选择的方法。

为此,我采用分层方法

  1. WCF合同 这是高度静态的,只有在绝对必要时才会改变 每个新合同都会收到一个新的命名空间/ URI 合同不会继承先前版本 - 这样做会阻止您弃用功能。

  2. WCF服务实施 这个实现或实现只是一个SHIM层 - 它接收请求并将其传递给适当的逻辑层。

  3. 逻辑层/适配器 如果请求已经到达最新版本合同,则立即处理。 如果请求已经到达先前版本的合同,则为该版本定位适配器(如果您愿意,这实际上可以在服务实现中发生),并且请求被传递给适配器。

  4. 适配器负责接收旧请求,并使其适应下一个较新版本的命名空间。这以链式方式工作,例如,如果从v1.0客户端收到请求到v1.3服务器

    1.0 contract -> 
        1.0 to 1.1 adapter -> 
            1.1 to 1.2 adapter -> 
                1.2 to 1.3 adapter -> 1,3 implementation. (and back if not one-way)
    

    每个适配器都有机会执行下一版本处理请求。 例如,在1.1方法中,您可能已经引入了要求传递“请求日期”的要求,但是您知道可以“做出最佳猜测”,因此您在传递请求之前在1.0适配器中添加该参数1.1逻辑。

    请记住,仍然可以引入不能“假定”或“默认”的要求 - 这些将破坏合同变更,而您只希望在绝对必要时执行此操作。但是因为你没有链接你的合同,你可以暂时支持这两种方法,然后从支持中删除旧合同,并且所有旧方法都会消失。

    接下来,您还可以选择将实体分成另一个可以独立于逻辑协定进行版本控制的命名空间。另一条鱼。

    您还需要决定支持旧合同的时间 - 您支持它们的时间越长,“版本处理”逻辑就越复杂。在像上面这样的实现中链接这个逻辑的好处是,一旦你为特定版本编写了适配器层,你就不必重新访问它。

    希望这给了你一些思考的东西。