WCFChannelFactoryとプロキシの生成


82

ChannelFactoryを使用して呼び出しを呼び出すことができるのに、どのような状況でWCFサービスからプロキシを生成したいのか疑問に思っていますか?

このようにして、プロキシを生成する必要がなく、サーバーが更新されたときにプロキシを再生成することを心配する必要はありませんか?

ありがとう


常にChannelFactoryを使用してください。私はこれを十分に強く述べることはできません。
tom redfern 2018

回答:


88

WCFクライアントを作成する基本的な方法は3つあります。

  1. VisualStudioにプロキシを生成させます。この自動生成は、WSDLを読み取ることによってサービスに接続するコードを生成します。何らかの理由でサービスが変更された場合は、サービスを再生成する必要があります。これの大きな利点は、セットアップが簡単なことです。VSにはウィザードがあり、すべて自動です。不利な点は、VSに依存してすべてのハードワークを実行しているため、制御できなくなることです。

  2. ChannelFactory既知のインターフェースで使用します。これは、サービス(サービスコントラクト)を説明するローカルインターフェイスがあることに依存しています。大きな利点は、変更をはるかに簡単に管理できることです。変更を再コンパイルして修正する必要がありますが、コードを再生成するのではなく、新しいインターフェイスを参照しています。通常、これはサーバーとクライアントの両方を制御するときに使用されます。どちらも単体テスト用にはるかに簡単にモックできるためです。ただし、インターフェイスは、RESTサービスを含め、どのサービスでも作成できますこのTwitterAPIをご覧ください

  3. 独自のプロキシを作成します。これは、特にRESTサービスの場合、HttpClientまたはを使用して行うのはかなり簡単WebClientです。これにより、最もきめ細かい制御が可能になりますが、多くのサービスAPIが文字列に含まれるという犠牲が伴います。例:var content = new HttpClient().Get("http://yoursite.com/resource/id").Content;-APIの詳細が変更された場合、実行時までエラーは発生しません。

個人的に私はオプション1が好きではありませんでした-自動生成されたコードに依存することは厄介で、あまりにも多くの制御を失います。さらに、シリアル化の問題が発生することがよくあります。2つの同一のクラス(1つはサーバーコード内にあり、もう1つは自動生成されます)になってしまいます。

オプション2は完璧なはずですが、チャネルは少し制限が多すぎます。たとえば、HTTPエラーの内容が完全に失われます。とは言うものの、サービスを説明するインターフェースを持つことは、コーディングと保守がはるかに簡単です。


4
@MurHafいいえ-この答えは完全に私自身の仕事です。私は常に他人の貢献を帰します。この回答は、さまざまな仕事で.NetのSOAPサービスを長年使用してきたことに基づいて作成しました。あなたがリンクしているその記事は2013年3月のものですが、私の答えは2010年4月に書かれました-3年前です!盗作が発生した場合、彼は私をコピーしました。非常に簡単なので、告発する前に日付を確認する必要があります。
キース

@MurHaf同じ結論に達することすらありません-その記事では、プロキシ(オプション1)を「単純」として自動生成することを推奨しています。セットアップは簡単ですが、維持するのが面倒で面倒だと説明します。彼はあなた自身のプロキシを書くことさえ議論していません(オプション3)。
キース

1
これはクライアントを「作成」する最も一般的な方法の1つであるため、SvcUtilについても言及する必要があると思います。
Mare Infinitus 2014

21

ChannelFactoryをMetadataResolver.Resolveメソッドと一緒に使用します。クライアントの構成が面倒なので、サーバーから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でも機能します。


すごいもの。configにもMetadataResolver.Resolveを使用していますが、サーバーからのバインディングを解決することは考えていませんでした。とても良い点です!
スリーパースミス

言及にThe main point of using ChannelFactory to get rid of the WCF client config
賛成

11

使用ChannelFactory<T>するには、サービスとクライアントの間で契約アセンブリを喜んで共有する必要があります。これで問題がなけれChannelFactory<T>ば、時間を節約できます。


@ Charles-なぜこれが真実ではないのか説明できますか?
Aran Mulholland 2011

6
@Aran:Andrewの言うことは正しいと思います。契約クラスの複製を生成したくない場合は、オリジナルにアクセスする必要があります。いずれにせよ、これらのコントラクトクラスが必要なのは事実です。それらを生成したり、手動で記述したり、サービスのソースコードを取得したりできます(同じ言語の場合)。アセンブリを共有するのが最も簡単な方法ですが、それが常に可能であるとは限りません。(多分私はアンドリューを文字通りに取りすぎているかもしれませんが、ここでは明確さが重要です。)
Igby Largeman 2011

2
@Charlesわかりました。つまり、Tのインターフェイスを手動でコーディングして使用することで、アセンブリにアクセスできなくてもChannelFactory <T>を使用できるということです。
Aran Mulholland 2011

1
@Aran:はい、手動でコーディングするか、svcutilなどのツールを使用します(サービスが実行されていてアクセス可能であると想定しています)。
Igby Largeman 2011

9

プロキシは非同期関数を構築しますが、これはちょっといいです。


2
はい-同時に、Visual Studioの「サービス参照の追加」とコマンドラインのsvcutil.exeの両方が、認識を超えて構成を破壊します。少なくともsvcutil.exeを使用すると、「/ noconfig」スイッチを定義できます。 .....
marc_s 2009年

1
ChannelFactoryは非同期メソッドも提供します:msdn.microsoft.com/en-us/library/ms731177.aspxしかし、私はT4テンプレートを使用して、同期メソッドを呼び出すThreadPoolを使用して非同期クラスを作成することを好みます。
SandRock 2011

1
更新として:.NET 4.5では、ChannelFactory <T>はタスクベースの非同期関数もサポートします。
gimpf 2013年

8

私の答えは、キースアンドリュー・ヘアの答え要約のようなものです。

サーバーを制御せず、WSDL / URLのみを使用している場合は、VisualStudioまたはsvcutilを使用してプロキシを生成します。(svcutilがより適切に機能する場合、Visual Studioが失敗することがあることに注意してください)。

サーバーとクライアントの両方を制御する場合は、インターフェース/コントラクトを共有し、ChannelFactoryを呼び出します


2

時間の節約だけではありません。WSDLで生成されたプロキシを使用することは危険です。サービス参照の更新を忘れると、ソリューションが一貫性のない状態のままになる可能性があるためです。すべてがコンパイルされますが、サービス契約は破られています。可能な限りChannelFactoryを使用することを強くお勧めします。そうすれば、作業がはるかに楽になります。

考えられる代替案は、プロジェクトをビルドするたびにSVCUtilユーティリティを呼び出してプロキシを作成するビルド前スクリプトを作成することですが、とにかくChannelFactoryの方がはるかに洗練されています。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.