ChannelFactoryを使用して呼び出しを呼び出すことができるのに、どのような状況でWCFサービスからプロキシを生成したいのか疑問に思っていますか?
このようにして、プロキシを生成する必要がなく、サーバーが更新されたときにプロキシを再生成することを心配する必要はありませんか?
ありがとう
ChannelFactoryを使用して呼び出しを呼び出すことができるのに、どのような状況でWCFサービスからプロキシを生成したいのか疑問に思っていますか?
このようにして、プロキシを生成する必要がなく、サーバーが更新されたときにプロキシを再生成することを心配する必要はありませんか?
ありがとう
WCFクライアントを作成する基本的な方法は3つあります。
VisualStudioにプロキシを生成させます。これにより、WSDLを読み取ることでサービスに接続するコードが自動生成されます。何らかの理由でサービスが変更された場合は、サービスを再生成する必要があります。これの大きな利点は、セットアップが簡単なことです。VSにはウィザードがあり、すべて自動です。欠点は、すべてのハードワークをVSに依存しているため、制御できなくなることです。
ChannelFactory
既知のインターフェースで使用します。これは、サービス(サービスコントラクト)を記述するローカルインターフェイスがあることに依存しています。大きな利点は、変更をはるかに簡単に管理できることです。変更を再コンパイルして修正する必要がありますが、コードを再生成するのではなく、新しいインターフェイスを参照しています。通常、これはサーバーとクライアントの両方を制御するときに使用されます。どちらも単体テストではるかに簡単にモックできるためです。ただし、インターフェイスは、RESTサービスを含め、任意のサービス用に作成できます。このTwitterAPIをご覧ください。
HttpClient
独自のプロキシを作成します。これは、特にRESTサービスの場合、またはを使用して行うのはかなり簡単ですWebClient
。これにより、最もきめ細かい制御が可能になりますが、多くのサービスAPIが文字列に含まれるという犠牲が伴います。例:var content = new HttpClient().Get("http://yoursite.com/resource/id").Content;
-APIの詳細が変更された場合、実行時までエラーは発生しません。
個人的に私はオプション1が好きではありませんでした-自動生成されたコードに依存することは厄介で、あまりにも多くの制御を失います。さらに、シリアル化の問題が発生することがよくあります。2つの同一のクラス(1つはサーバーコードにあり、もう1つは自動生成されます)になります。
オプション2は完璧なはずですが、チャネルは少し制限が多すぎます。たとえば、HTTPエラーの内容が完全に失われます。とはいえ、サービスを説明するインターフェースを使用すると、コーディングと保守がはるかに簡単になります。
私はMetadataResolver.Resolveメソッドと一緒にChannelFactoryを使用します。クライアントの構成が面倒なので、サーバーからServiceEndpointを取得します。
ChannelFactory(Of T)を使用する場合、Tは、プロジェクト内の参照から取得できる元のコントラクト、または生成されたコントラクトインスタンスのいずれかです。一部のプロジェクトでは、コントラクトdllへの参照を追加できなかったため、サービス参照からコードを生成しました。サービス参照を使用して非同期コントラクトを生成し、ChannelFactoryでそのコントラクトインターフェイスを使用することもできます。
ChannelFactoryを使用する主なポイントは、WCFクライアントの構成情報を削除することでした。以下のサンプルコードでは、構成なしでWCFクライアントを実現する方法を確認できます。
Dim fixedAddress = "net.tcp://server/service.svc/mex"
Dim availableBindings = MetadataResolver.Resolve(GetType(ContractAssembly.IContractName), New EndpointAddress(fixedAddress))
factoryService = New ChannelFactory(Of ContractAssembly.IContractName)(availableBindings(0))
accesService = factoryService.CreateChannel()
私の最後のプロジェクトでは、availableBindingsがチェックされ、net.tcpまたはnet.pipeが使用可能な場合はそれが使用されます。そうすれば、自分のニーズに合わせて利用可能な最良のバインディングを使用できます。私はメタデータエンドポイントがサーバー上に存在するという事実だけに依存しています。
これがお役に立てば幸いです
ところで、これは.NET3.5を使用して行われます。ただし、4.0でも機能します。
使用するにChannelFactory<T>
は、サービスとクライアントの間で契約アセンブリを喜んで共有する必要があります。これで問題がなければChannelFactory<T>
、時間を節約できます。
プロキシは非同期関数を構築しますが、これはちょっといいです。
私の答えは、キースとアンドリュー・ヘアの答えの一種の要約です。
サーバーを制御せず、WSDL / URLのみを使用している場合は、VisualStudioまたはsvcutilを使用してプロキシを生成します。(svcutilがより適切に機能する場合、Visual Studioが失敗することがあることに注意してください)。
サーバーとクライアントの両方を制御する場合は、インターフェース/コントラクトを共有し、ChannelFactoryを呼び出します
。
時間の節約だけではありません。WSDLで生成されたプロキシを使用すると危険です。サービス参照の更新を忘れると、ソリューションが一貫性のない状態のままになる可能性があるためです。すべてがコンパイルされますが、サービス契約は破られています。可能な限りChannelFactoryを使用することを強くお勧めします。そうすれば、作業がはるかに楽になります。
考えられる代替案は、プロジェクトをビルドするたびにSVCUtilユーティリティを呼び出してプロキシを作成するビルド前スクリプトを作成することですが、とにかくChannelFactoryの方がはるかに洗練されています。