所以你正在做一个“服务器推送”?即您的固定 IP 硬件作为客户端运行,而动态 IP 机器正在运行 ServiceHost?
我真的希望有一个“智能层”,可以简单地放置在这里处理版本控制 - 但真的没有灵丹妙药。
IExtensibleObject 确实只是为往返维护数据,但如果服务器只有旧合约,那么它也只有旧实现,因此无法“使用”这个“扩展”信息。
您可以遵循以下几种做法。主要区别在于,更改版本号,或者不要……在 WCF 合同的情况下,没有版本号,但版本被编码到合同命名空间/URI 中。
如果您不更改命名空间,那么您基本上是在说,“我将拥有一项服务,它永远不会破坏向后兼容性(嗯,对于 X 版本)”。然后,您必须实施严格的开发实践,以确保没有修改或删除任何方法,只能进行添加。这将阻止客户端发送服务器不再理解的请求。
另一种方法是在每次修订合同时更改 WCF 合同 URI/命名空间。然后,您的“服务器”将拥有您想要支持的每个版本的合同的实现。例如,如果您为 3 个先前版本的客户提供支持,他们可能正在运行最新的 WCF 服务器,但 WCF 客户端不得早于 3 个版本,否则 WCF 服务器将无法理解请求(因为 URI/合同命名空间将不存在)。
这通常是我选择的方法。
为此,我有一个分层的方法
WCF 合同
这是高度静态的,仅在绝对必要时更改
每个新合约都会收到一个新的命名空间/URI
合同不会从以前的版本继承 - 这样做会阻止您弃用功能。
WCF 服务实现
这个实现或实现只是一个 SHIM 层 - 它接收请求并将其传递给适当的逻辑层。
逻辑层/适配器
如果请求已到达最新版本的合同,则立即处理。
如果请求到达之前的版本合同,则为该版本定位一个适配器(如果您愿意,这实际上可以在服务实现中发生),并将请求传递给适配器。
适配器负责接收旧请求,并将其调整到下一个较新版本的命名空间。这以链接方式工作,因此,例如,如果从 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 逻辑。
请记住,仍然有可能引入不能“假定”或“默认”的要求 - 这些会破坏合同变更,您只希望在绝对必要时这样做。但是因为你没有链接你的合约,你可以暂时支持这两种方法,然后从支持中删除旧合约,它的所有旧方法都消失了。
接下来,您还可以选择将实体分离到另一个命名空间中,该命名空间可以独立于逻辑合约进行版本控制。再来一壶鱼。
您还需要决定支持旧合约多长时间 - 支持它们的时间越长,您的“版本处理”逻辑就会变得越复杂。在上述实现中链接此逻辑的好处是,一旦您为特定版本编写了适配器层,您就不必重新访问它。
希望这能让你有所思考。