この質問は、時間の経過とともに進化しやすくするためのWCFサービスの設計方法に関するものです。 問題を説明することなくこれに対する応答の深さを得ることは困難です。WCF Architecture、およびバージョン
背景
私は、WCFサービスとクライアントの大規模なシステムを開発しています。 このコードを実行しているサーバーが10台しかないため、サーバー側の更新は簡単です。
高度な自動化にもかかわらず、クライアントは30万人以上のWCFクライアントで更新するのが非常に難しく、更新には常に時間がかかり、2〜3週間にわたって高い更新成功率しか達成できません。
データは
[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)の私の最初の実装は、独自のアセンブリ内の1つのアセンブリ、ServiceContract
、および実装にDataContract
になってしまいました。
クライアントは、ほぼすべてのプラグインでMyContractFactory
のコピー&ペーストして、非常に醜い、
MyWebService1.MyContract
MyWebService2.MyContract
になってしまいました。 DataContract
は同じですが、クライアントにはDataContract
アセンブリが含まれていなかったため、異なるオブジェクトとして異なる名前空間に表示されました。
実装2つの
クライアントが今DataContract
アセンブリを含む、ServiceContracts
は、サービスの実装に別のアセンブリであり、それはコードの再利用(これ以上のコピーに役立つ場合、クライアントはServiceContract
アセンブリの一部を含むことができペースト)。私は今の困難に直面しています第2の実施と
質問
、どのように私は私の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
}
と、次の設定2つの異なる名前を持つ2つの契約で
<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つの別々のサービスである必要がありますか?
アップデート2
私は更新1で説明している方法を使用して終了。 WSDLは間違っていますが、これをテストしたときに古いクライアントの下位互換性があります。
、ありがとう! –
@ marc-sあなたは同じ契約名を保持できるようには思われません。 –
@MAfifi:いいえ - どちらもお勧めしません!サービス契約のようなインターフェースは**不変です** - 何かを追加する必要がある場合は、新しい名前を付ける必要があります。もちろん、既存のインターフェースを破ることは決してありません。パラメータの数やデータ型... –