WCF架构和Evolution,版本
这个问题围绕如何构建WCF服务以使其随着时间的推移变得容易。 在没有描述问题的情况下很难得到对此的响应深度。
背景
我正在开发一个大型的WCF服务和客户端系统。 服务器端“易于”更新,因为只有10个服务器运行此代码。
客户很难更新,尽管自动化程度很高,但在300,000多个WCF客户端,更新总是需要时间,并且只能在两到三周的时间内实现高更新成功率。
数据合同
[DataContract] public class MyContract { [DataMember] public int Identity {get; set;} [DataMember] public string Name {get; set;} // More members }
DataContract
很难初始化,并且有一个标准的MyContractFactory
类来初始化为您的机器获取适当的实例。
public class static MyContractFactory { public static MyContract GetMyContract() { // Complex implementation } }
ServiceContracts
DataContract
在一系列Web服务中非常常见。
namespace MyPrefix.WebServicve1 { [ServiceContract] public class IMyInterface1 { [OperationContract] public void DoSomethingWithMyContract(MyContract data); } [ServiceContract] public class IMyInterface2 { [OperationContract] public void DoSomethingDifferentWithMyContract(MyContract data); } }
客户
我的客户端是插件,插件运行在单独的进程或应用程序域中,具体取决于我们在该插件中的信任级别。
实施1
我对此(默认WCF)的初始实现以一个程序集中的DataContract
, ServiceContract
和自己的程序集中的实现结束。
客户最终非常难看,
MyWebService1.MyContract MyWebService2.MyContract
在几乎每个插件中都复制并粘贴了MyContractFactory
。 虽然DataContract
是相同的,但客户端不包含DataContract
程序集的事实意味着它在不同的名称空间下显示为不同的对象。
实施2
客户端现在包含DataContract
程序集, ServiceContracts
位于服务实现的单独程序集中,客户端可能包含一些ServiceContract
程序集,如果它有助于代码重用(不再复制和粘贴)。
题
在第二个实现中,我现在面临的困难是,如何更新我的DataContract
和ServiceContracts
?
-
我是否更新相同的程序集并增加版本号? 在所有客户端升级的同时,如何保持向后兼容性? 打破客户端直到他们更新是不可接受的。
-
我是否使用扩展
MyDataContract
的类创建一个新程序集,在新的ServiceContract
下接受新类型的新方法? 这是否意味着我的合同每次微小的改变都需要新的assembly? 我怎么能阻止它在几年内达到几百个呢? -
其他解决方案?
无论我想到什么解决方案,它们似乎都有一个重大的缺点。
似乎没有(至少对我而言),
运营合同复杂性
[OperationContract] public void DoSomethingWithMyContract(MyContract data); [OperationContract(Name = "DoSomethingWithMyDataByAdditionalData"] public void DoSomethingWithMyContract(MyContract data, MyContract2 additionalData);
我正在寻找一个在大规模环境中工作了一段时间的解决方案。 博客条目等非常受欢迎。
更新1
纵观使用“无模式”更改的局限性,不同的命名空间似乎是唯一可靠的方法。 但是,它没有按预期工作,例如下面
[ServiceContract( Name = "IServiceContract", Namespace = "https://myurl/2012/05")] public interface IServiceContract1 { // Some operations } [ServiceContract( Name = "IServiceContract", Namespace = "https://myurl/2012/06")] public interface IServiceContract2 { // Some different operations using new DataContracts }
有以下服务
public class MyService : IServiceContract1, IServiceContract2 { // Implement both operations }
和以下配置
结果有两个不同免费精选名字大全的合同,我希望我可以指出我的客户,
https://myurl.com/MyService.svc/2012/05旧版本和https://myurl.com/MyService.svc/2012/06
,但似乎我想保留ServiceContract名称,他们必须是两个单独的服务,而不是相同服务的单独端点地址?
更新2
我最终使用了我在更新1中描述的方法。 虽然WSDL看起来不对,但是当我测试它时,该服务确实在旧客户端下向后兼容。
微软和大多数受人尊敬的WCF专家都可能会说同样的事情:应该使用合同命名空间来处理版本控制。
我不是指程序集的.NET命名空间 – 我的意思是实际的WCF服务(和数据协定)命名空间 – 所以你应该:
[ServiceContract(Namespace="https://services.yourcompany.com/Service1/V01"]
或类似的东西 – 一些人喜欢按年/月的版本:
[ServiceContract(Namespace="https://services.yourcompany.com/Service1/2012/05"]
这允许您拥有相同服务的多个版本,并且只要客户端使用旧版本(由服务名称空间指示)调用,它们就会获得旧版本(只要您仍然公开它)。
看到:
上述就是C#学习教程:WCF架构和Evolution,版本分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/cdevelopment/1038995.html