0

私は新しいですが、wcf に関する記事を読んでいると、ServcieContrcatを変更すると、サービス側だけでなくクライアント側も変更する必要があり、管理が非常に難しいことがわかりました。

Example 1:

開発者は、次の関数を使用して、注文処理用の WCF サービスを作成する必要があります。GetOrderById, GetOrdersByStatus, SaveOrder

ServiceContract は次のようになります。

[ServiceContract]
public interface IOrderService
{
    [OperationContract]
    Order GetOrderById(int orderId);

    [OperationContract]
    List<Order> GetOrdersByStatus(OrderStatus orderStatus);

    [OperationContract]
    void SaveOrder(Order order)
} 

たとえば、数か月後、プロジェクト マネージャーは次のように言いますDeleteOrderById, GetOrdersByCustomerIdGetOrdersByStatusGetOrdersByStatusAndCustomerId

開発者は、ServiceContrcatクライアントを更新して更新する必要があります。ご覧のとおり、変更ServiceContrcatは非常に困難です。

そのため、機能を拡張したり、何らかの変更を加えたりしても問題を引き起こさないwcfサービスを開発するための最良のガイダンスを探していますが、クライアントエンドは問題に直面しません。ありがとう

一人の男が同じ状況で前に答えた

これは私がやったことです: 私の 30 以上の関数 (およびリストはどんどん大きくなります) はすべて、入力パラメーターと出力パラメーターの両方として、データ型として文字列、int、bytes() を取り、マスターの単一のエンドポイントと受信する関数を作成しました。入力パラメータであり、単一の単純なクラスを出力として送り返します。HostInterface と呼ばれるこのクラスには、文字列 (すべての文字列と int をカプセル化するために使用) と byte() 配列 (すべてのバイナリを詰め込む) の 2 つのパラメーターのみが含まれます。

そのため、クライアントが 1 つの文字列パラメーターだけで Ping() のような単純なものを呼び出している場合でも、ResumeDownload() のように 5 つの文字列、2 つの int と 1 つのバイト配列を使用して複雑なものを呼び出している場合でも、これらのパラメーターはすべて HostInterface クラス (文字列) にカプセル化されます。 int を 1 つの String パラメータ (XML として) に変換し、バイトを byte フィールドに変換します。

彼の答えに感謝しますが、それを実装する方法が本当にわかりません。誰かがこのURLにアクセスすると、クライアントに影響を与えないWCFサービス契約を変更する方法は?

それから彼が言ったことを知っています。

後でサービス コントラクトの機能を拡張した場合に、サービスを利用するクライアントが問題に直面しないように、サービス コントラクトを設計する方法を視覚化するのに役立つ小さな完全な wcf サービス コードを探しています。

この状況を解決するための他の可能なガイドラインを教えてください。ありがとう

4

2 に答える 2

2

一般的なエンドポイントを作成するという提案は悪い考えだと思います。あらゆる種類の入力を受け取るメソッドを作成すると、C# の WCF で得られる強力な型指定の利点がすべて失われます。古いクライアントを処理するという大変な作業は依然として必要ですが、受信するデータを検査し、それが想定する「バージョン」をヒューリスティックに決定することにより、アプリケーション コードでそれを行う必要があります。id私の考えでは、これは 、data1data2data3、などの名前の多数の列を持つ単一の SQL データベース テーブルを作成しdata4、その 1 つのテーブルにあらゆる種類の無関係なデータを格納することに似ています。

必要なコントラクトの変更に後方互換性がある場合は、インプレースでコントラクトに追加できます。新しいメソッドの追加は、既存のメソッドの可用性に影響しないため、下位互換性があります。

下位互換性のない変更 (メソッドの削除や既存のパラメーターの変更など) を行う必要がある場合、最も簡単な解決策は、新しいアドレスに存在する新しいコントラクトを作成することです。コントラクトのバージョン 1 が http://example.com/v1/MyService に達した場合、バージョン 2 は http://example.com/v2/MyService に達します

コントラクトがあまり変更されていないクラス間で多くのコードが重複するのを避けるために、コントラクトを実装するクラスは互いに継承する場合があります。これを行う1つの方法は次のとおりです。

namespace V1
{
    [ServiceContract]
    public interface IService { ... }
    public class MyService : IService { ... }
}

namespace V2
{
    [ServiceContract]
    public interface INewService { ... }
    public class MyNewService : V1.MyService, INewService { ... }
}

または、コンポジションを使用できます。

public class MyNewService : INewService
{
    private readonly V1.MyService v1service = new V1.MyService();

    public int SomeMethod()
    {
        return this.v1service.SomeMethod();
    }
}

このように、MyNewServiceのすべての機能を実装しますが、 WCF を介して使用できるのはMyServiceによって公開されるメソッドのみです。INewServicev2 URL を介してサービスにアクセスする人は誰でも、新しい機能を利用できます。古いサービスを使用しているクライアントは、アップグレードの準備が整うまで引き続き v1 URL を使用します。

于 2014-01-30T08:17:27.237 に答える