2011-02-10 4 views
0

私は最近WCFの使用を開始しましたが、サービスリファレンスの追加で生成されたクライアントクラスはIMyInterfaceというServiceContractのインターフェイスを実装していないことに驚きました。代わりにSystem.ServiceModel.ClientBase<IAnotherInterface>, IAnotherInterfaceを実装します。ここで、IAnInterfaceのようなインターフェイスで、のServiceContractインターフェイスですが、実際は同じものではありません。いくつかのタイプが異なることがわかります。リストの代わりに配列があります。生成されたクライアントクラスがServiceContractインターフェイスから継承しないのはどうですか?

ウェブサービスへのリモート呼び出しをしたいときや時にはローカルオブジェクトを使用したいことがあるので、同じインターフェースを実装したいと思うので、これはちょっと面倒です。現在私はClientBaseオブジェクトを別のものにラップしていますので、同じインターフェイスを実装し、すべての呼び出しをClientBaseオブジェクトに渡します。これは推奨されるアプローチですか、それとも簡単な方法ですか?

私は配列からListなどのサービスパラメータの設定を変更することができますが、基本的なタイピングの問題を解決するかどうかは疑問です。

答えて

0

WCFのデフォルト動作では、あなたが見ている正確に何である:サービスとクライアントが互いの全くに独立している - 相互運用可能であることのアイデアを持つすべての後に、あなたがされているクライアントに依存することはできません.NETでも、Ruby、Pythonにすることができます。

したがって、クライアントプロキシが作成されると、クライアントとサービスが共有するのは、ワイヤ上のメッセージの形式だけであり、SOAPの場合はサービスのWSDL記述です。クライアント側のプロキシは、同じメソッドを呼び出し、同じデータ構造を使用してサービスにメッセージをシリアライズする目的で、このメタデータに基づいて再作成されます。

通信の両端を制御でき、両方が可能な場合は、NETを使用すると、サービスとデータコントラクトを別のクラスライブラリに入れ、サービスとクライアントの間でそのアセンブリ(したがって正確なインターフェイスとクラス)を共有することで、これらのステップの1つをスキップできます。

クライアントプロジェクトがその共有アセンブリを参照していて、サービス参照を追加してダイアログボックスのデフォルトのオプションをそのまま残すと、参照アセンブリから既存のクラスとインタフェースを再利用する可能。この場合、サービス参照を追加すると、クライアントサイドプロキシのジェネレータは、サービス記述と完全に一致するクラスを見つけ、クラスとインタフェースの独立した独立したセットを生成する代わりにそれらを使用します。

2

私はあなたのサービスインターフェイスを別のライブラリ(DLL /プロジェクト)に移動したいと思います。

SvcUtil.exeのオーバーロードがあります。これにより、クライアントのプロキシを生成して、インターフェイスのライブラリ(DLL)を渡して複製しないようにすることができます。私は旗が-rまたは-referenceか何かのようだと思う...

1

あなたはAdd Service ReferenceまたはSvcUtilを使う必要はありません。インターフェイスを使用するクライアントプロキシを手動で作成できます。デフォルトのコンストラクタを使用するには、web.configにバインディングが必要です。また、エンドポイントとバインディングを渡すこともできます。

この方法の大きな利点の1つは、インターフェイスを変更してプロキシを再生成する必要があるたびに、SvcUtil.exeを操作する必要がないことです。このクラスがインターフェイスを正しく実装していないことを示す代わりに、コンパイルエラーが発生します。

SvcUtilとAdd Service Referenceは、元のサービスインターフェイスや契約にアクセスできないリモートサービスで主に使用されます。このユーティリティは単にサービスwsdlを読み込み、それを生成します。したがって、あなたのプロジェクトにすでにあるものと衝突しないことを確認するために狂った名前を付けます。

また、上記のReddogのように、サービスとデータコントラクトを別のプロジェクト/ dllに移動すると、これらを簡単に参照できるようになります。

public partial class MyServiceClient : System.ServiceModel.ClientBase<MyProject.Contracts.IMyService>, MyProject.Contracts.IMyService 
    { 

    #region IMyService Members 

    public void RecordSearchAnalytics(int a, int b, int c, string d, string e) 
    { 
     base.Channel.RecordSearchAnalytics(a, b, c, d, e); 
    } 

    #endregion 

    #region boiler plate code 
    public MyHServiceClient() 
    { 
    } 

    public MyHServiceClient(string endpointConfigurationName) : 
     base(endpointConfigurationName) 
    { 
    } 

    public MyHServiceClient(string endpointConfigurationName, string remoteAddress) : 
     base(endpointConfigurationName, remoteAddress) 
    { 
    } 

    public MyHServiceClient(string endpointConfigurationName, System.ServiceModel.EndpointAddress remoteAddress) : 
     base(endpointConfigurationName, remoteAddress) 
    { 
    } 

    public MyHServiceClient(System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress remoteAddress) : 
     base(binding, remoteAddress) 
    { 
    } 

    #endregion 




    } 
関連する問題