2

以下のソース コードに示されている動作を実現する方法を探しています。「常にメッセージ コントラクトを生成する」オプションを使用して WCF サービス プロキシを作成しました。すべての要求および応答メッセージ コントラクトは共通のインターフェイスを実装しており、同じ関数を使用してそれらを実行したいと考えています。クライアントプロキシを介してメッセージを送信する一般的な方法があるはずですが、どこにも見つかりません。どんな助けでも大歓迎です!

// I can do this
private IPagedResponse GetAllFoods()
{
    NutrientDBClient client = new NutrientDBClient();
    GetAllFoodsRequest request = new GetAllFoodsRequest();
    GetAllFoodsResponse response = client.GetAllFoods(request);

    return response;
}
// I'd like to do this
private IPagedResponse ExecutePagedRequest(IPagedRequest request)
{
    NutrientDBClient client = new NutrientDBClient();
    IPagedResponse response = (IPagedResponse)client.Execute(request);

    return response;
}

現在、ExecutePagedRequest(IPagedRequest) メソッドを NutrientDBClient に追加し、IPagedRequest の具象型に基づいて正しいサービス操作を手動で実行しています。メッセージ コントラクトに IPagedRequest を簡単に実装でき、自動的に魔法のように機能するように、よりエレガントな方法を探しています。

4

2 に答える 2

2

本当に達成したいことを 100% 確信しているわけではありませんが、WCF の基本をいくつか説明させてください。

多くのプログラマーは、WCF をある種の .NET リモート処理であると誤解しています。たとえば、彼らは基本的に、遠く離れたサーバー上のリモート オブジェクトにアクセスして、どこかの「リモート」.NET オブジェクトのメソッドを呼び出していると考えています。そんなことは絶対にありません!

WCF はメッセージングに関するものです。クライアントとサーバーは、シリアル化されたメッセージ(および場合によってはヘッダー) のみを交換しますが、それだけです。

つまり、これらのメッセージ交換メカニズムは、.NET 以外の多くのプラットフォーム (Java や Ruby など) と相互運用できるように設計されています。WSDL および XSD メカニズムを利用して、操作の記述 (WSDL) と交換されるデータ構造 (XSD) を交換します。

WSDL と XSD はすべて、明確に定義された明示的な呼び出しとデータ構造に関するものです。これらの標準によって提供される機能は、すべての SOA プラットフォーム間の最小公分母です。そのため、純粋な .NET を使用して慣れ親しんだものよりもかなり制限されています。SOA の世界と OOP の世界は必ずしも一致するとは限りません。

最終的に、本当に理解してプログラミングする必要があるのは、WSDL/XSD によって定義された標準です。そのため、ジェネリック、インターフェイス、およびそれらのインターフェイスを実装するクラスなど、.NET のすべての機能についてすぐに忘れる必要があります。それらは、WCF メッセージング インフラストラクチャでは機能しません。

WCF クライアントと WCF サーバー間で交換できるのは、XML スキーマで記述および表現できるもの (文字列、整数などの基本的なデータ型で構成される具体的な型) だけです。XSD は多少の継承をサポートしていますが、ジェネリクスについて詳しく説明しておらず、インターフェイスや非具象クラスをまったく扱っていません。

したがって、すぐに使用できるように、汎用インターフェイスとそのインターフェイスを実装するメッセージ、およびそのクラスに基づいて呼び出す実際のメソッドをWCFが把握するというアプローチは考えられません。これは、WCF が動作するように設計および設計された方法ではありません。

カスタムの (ただし具象的な) 基本クラスを作成できる可能性があります。また、サーバー側で WCF 操作ディスパッチャーを拡張して、渡されるクラスに基づいてさまざまなメソッドを呼び出すことができる場合があります (または、ヘッダーに含まれる追加情報)乗り物に沿って)-しかし、それは簡単ではないと思いますし、実際にWCFが機能するように意図されている方法でもありません-あなたが本当にそれをやってのけることができるという保証はありません.

于 2010-01-10T21:00:20.230 に答える
0

以下は、私がこの問題をどのように解決したかです。私のメッセージ契約は、IPagedRequest と IPagedResponse を実装します。NutrientDBClient は、私のコード生成クライアント プロキシ (ClientBase) です。ExecutePagedRequest() は、リクエストの具体的なタイプに基づいてメッセージ ルーティングを行います。

public interface IPagedRequest
{
    PagingContext PageInfoState { get; set; }
}

public interface IPagedResponse
{
    PagingContext PageInfoState { get; }
    IEnumerable ResultItems { get; }
}

public partial class NutrientDBClient : IHasPagedServiceOperations
{
    public IPagedResponse ExecutePagedRequest(IPagedRequest request)
    {
        if (request == null) { throw new ArgumentNullException("request"); }

        if (typeof(GetAllFoodsRequest).IsAssignableFrom(request.GetType()))
        {
            return GetAllFoods((GetAllFoodsRequest)request);
        }

        // Other Service Operations that take IPagedRequest and 
        // return IPagedResponse removed for example


        throw new NotSupportedException(
            string.Format("Paged requests of type {0} are not supported.",
                request.GetType().Name));
    }
}
于 2010-01-11T13:08:27.713 に答える