2012-01-13 13 views
2

私はテスト目的で依存関係注入を使用して実装された一連のWCFサービスを持っています。私はただのインターフェイスを使用して、サービスコンストラクタのコンポーネントとしてそれらを注入リポジトリとWCFサービスの両方をあざけることができ、私のユニットテストのようWCFと依存性注入

基本的にこれらのサービスは、時々、お互いを呼び出します。

これは、これらのサービスをどのような依存関係もなく適切にテストできるので、素晴らしいことです。

は、私はまた、(ごみの多くを作成します)Visual Studioのサービス参照を使用しないようにするために、自分のプロキシを実装しているので、私はのChannelFactory CreateChannelメソッドを使用しています。

私は少し生きている環境で起こることを心配しています。

何が起こるかというと、他のWCFサービスを呼び出す私のWCFサービスは、コンストラクタで、私は一度使用このオブジェクトを配置することはできません。このため、注入され、この外部コンポーネントのインスタンスを1つだけ持っていることです。

これは問題を引き起こすでしょうか? ガベージコレクタはそれを処理しますか? 接続は開いたままですか? このアプローチは間違っていますか?

ありがとうございます。

答えて

2

ChannelFactoryは、CreateChannelメソッドを呼び出すと、チャネルオブジェクトを作成します。このチャンネルオブジェクトは、実際に接続されているものです。あなたがチャネルに完了したら

、あなたはそれにIClientChannel.Closeメソッドを呼び出すことによって、それを閉じる必要があります。そのため、基盤となるネットワーク接続が閉じられるはずです。一部の状況では、チャネルがFaulted状態ではないことを最初に確認したとしても、Closeメソッドを呼び出すとCommunicationObjectFaultedException例外が発生することがあります。

あなたはCloseメソッドがwcfClientChannelオブジェクトで呼び出されcode example of this MSDN documentation pageで見ることができます。

+0

お返事をお寄せいただきありがとうございますが、私の問題は、あなたがメッセージレベルのセキュリティなどの横断的関心事に適用するために、他のIChannelInvoker<T>デコレータを追加できるように

呼び出しは、また、構成可能です接続を閉じる方法はありません。私はコンポーネントとしてWCF/Webサービスを注入し、サービス接続を適切に処理する方法を知りたいです。問題は、それをコンストラクタのパラメータとして持つことは、クラスレベルで私はそのインスタンスを1つしか持たず、別のメソッドが呼び出されたときに閉じられると例外が発生するということです。また、デフォルトでは、各サービスコールは異なるインスタンスであるため、これはたぶん哲学上の問題です。それが理にかなっていることを願っています。 – matteo75

+0

@ matteo75あなたのアプローチが「外部コンポーネント」であるかどうかは、私には分かりませんでした。チャンネルの工場なら、私は処分について心配する必要はありません。私はあなたのアプローチは良いと思うが、私はあなたのサービス実装がIDisposableを実装し、あなたに外部コンポーネントを処分させるだろう。 WCFがそれを尊重していることを確認するためにそこに侵入してください。 –

+0

私はChannelFactoryを使用していますが、現時点ではサービス廃棄を実装していません。私はそれがうまくいくと思ったが、私は、このリリースサービスの接続に起因する可能性のあるメモリの増加する使用(リサイクル後にリリースされる)にIISが気づいている。私は100%確信しているわけではありませんが、Dependency InjectionアーキテクチャのClose/Disposeサービスのベストプラクティスを知ることは素晴らしいことです。 – matteo75

0

はい、開いたチャンネルを閉じる必要があります。誰が実際にチャネルファクトリを使用してチャネルを開くのかを指定していません。ファクトリーを呼び出すことからオープンチャネルを受け取った人は誰でも、ファクトリーを閉鎖する責任があります。なぜなら、それが許可されている唯一の場所であるからです。

一般に、チャネルを開いて電話をかけ、直ちに閉じてプールに接続する必要があります。 ChannelFactory<T>はこのために最適化されており、実用的な場合に利用可能な接続を再利用し、契約の処理などは一度しか行われません。これらの点を考えると

は、私のお気に入りは、これまで明示的にこれらのオープン・ボーク・クローズのセマンティクスを定義するための別の抽象化をしています。私はと呼んでいますが、これは単一のExecuteメソッドです。私が今持っているバージョンは、唯一の非同期(async)であるが、ここでは簡単のために、ここのような同期バージョンが見えるものです:実装のExecute方法は、チャネルを開くためにChannelFactoryを使用してデリゲートを呼び出し、チャネルを閉じ

public interface IChannelInvoker<TChannel> 
{ 
    /// <summary> 
    /// Executes a method within the context of an open channel 
    /// </summary> 
    TResult Execute<TResult>(Func<TChannel, TResult> method); 
} 

、結果を返します。私は、そこに注入された工場を持って、アプリの生涯にわたって守っています。

サービスAでは、チャネルTを注入する代わりに、IChannelInvoker<T>を注入します。例えば: - ヘッダを追加するなど