這個問題是圍繞着如何構建WCF服務,使其隨着時間的推移而變得容易。 在不描述問題的情況下,很難獲得對此的響應深度。WCF體系結構和Evolution,版本
背景
我開發的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
是通過一系列的網絡服務非常普遍。
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)的一個組件,ServiceContract
,並實現在自己的裝配結束了與DataContract
。
的客戶幾乎每個插件結束了一個非常難看,
MyWebService1.MyContract
MyWebService2.MyContract
隨着MyContractFactory
的複製和粘貼。雖然DataContract
是相同的,但客戶端不包含DataContract
程序集這一事實意味着它出現在不同對象的不同名稱空間下。
實現2個
的客戶現在包括DataContract
裝配,ServiceContracts
是在一個單獨的裝配服務實現,客戶端可能包括一些ServiceContract
組件是否會與代碼重用(不再拷貝援助和粘貼)。
問題
隨着第二執行我現在面臨的困難,我該如何更新我的DataContract
和ServiceContracts
?
我是否更新相同的程序集並增加版本號?在所有客戶端升級時如何保持向後兼容性?打破客戶,直到他們更新是不可接受的。
我是否創建了一個新類,該類擴展了
MyDataContract
,在新的ServiceContract
下接受新類型的新方法?這是否意味着我的合同的每一個小改動都需要一個新的程序集?在幾年的時間內,我會如何阻止它達到數百個?其他一些解決方案?
無論我認爲通過什麼解決方案,他們都似乎有一個主要的缺點。
似乎沒有要(至少我)的,
- 保留向後兼容,直到客戶更新
- 保持客戶沒有膨脹修剪作爲軟件的發展隨着時間的推移
- 沒有明顯污染我的
ServiceContract
(OperationContract
的過載需要一個新的「名稱」)。我已經有了像下面這樣的東西,它讓我覺得隨着時間的推移而噩夢。
經營合同的複雜性
[OperationContract]
public void DoSomethingWithMyContract(MyContract data);
[OperationContract(Name = "DoSomethingWithMyDataByAdditionalData"]
public void DoSomethingWithMyContract(MyContract data, MyContract2 additionalData);
我尋找已超過在大型環境中一段時間工作的解決方案。博客條目等非常受歡迎。
更新1
翻翻使用「無模式」的變化的限制,不同的命名空間似乎是唯一可靠的方法。然而,它並不像預期的那樣工作,例如,下面
[ServiceContract(
Name = "IServiceContract",
Namespace = "http://myurl/2012/05")]
public interface IServiceContract1
{
// Some operations
}
[ServiceContract(
Name = "IServiceContract",
Namespace = "http://myurl/2012/06")]
public interface IServiceContract2
{
// Some different operations using new DataContracts
}
有以下服務
public class MyService : IServiceContract1, IServiceContract2
{
// Implement both operations
}
及以下配置
<service behaviorConfiguration="WcfServiceTests.ServiceBehavior"
name="Test.MyService">
<endpoint
address="2012/05"
binding="wsHttpBinding"
contract="Test.IServiceContract1">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint
address="2012/06"
binding="wsHttpBinding"
contract="Test.IServiceContract2">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
結果兩個合同有兩個不同的名字,我希望我能指出我的客戶,
http://myurl.com/MyService.svc/2012/05舊版本和http://myurl.com/MyService.svc/2012/06
,但似乎如果我想保留ServiceContract名稱,它們必須是兩個單獨的服務,而不是同一服務的單獨端點地址?
更新2
我最終使用我已下更新1中描述的方法。雖然WSDL看起來不正確,但是當我測試過這個服務時,該服務確實向下兼容老客戶端。
@馬克-S一些偉大的答案在這些鏈接,謝謝!仍然消化它們 –
@ marc-s似乎你不能保留相同的合約名稱? –
@MAfifi:不 - 你也不應該!這是一個基本原則,像服務合同這樣的界面是**不可變的** - 如果你需要添加一些東西給它,你需要給它一個新的名字。當然,你應該**永遠不會**通過改變例如打破現有界面。參數的數量或數據類型... –