4

WindowsサービスでホストされているWCFサービスを実行しています。 Unityを介してWCFサービスの依存関係が注入されますが、これはすべて良好です。その結果、このサービスはユニットテストを書くのも簡単です。DIとテストでWCF OperationContextをうまく動かす

最近、着信メッセージを検査するためにOperationContextを使用する機能をサービスに追加しました。残念なことに、これは、密封されたクラスや静的なクラス、インターフェイスや仮想メソッドの欠如のために、サービスのテスト容易性を水から吹き飛ばします。

このような状況では、.NET'ersのお気に入りのツールであるラッパークラスを使用しました。これは一般的な問題であるため、誰かがalready done the hard work for usです。これにより、IOperationContextの実装であるWCFサービスに新たな依存関係が追加されます。私の単体テストでは問題ありませんでした。NS代理店はMoqのような私の模擬フレームワークですが、.Objectの呪いはありません。

しかし、実際にサービスを起動しようとすると、IoCコンテナの登録が完了した時点で、ラップされているOperationContextが初期化されていないという問題があります。 (ここではユニティを使用して)私の初期化コードは次のとおりです。

container.RegisterType<IOperationContext, OperationContextWrapper>(new InjectionConstructor(OperationContext.Current)); 

が、この時点では、OperationContext.Currentnullので、Unityは速やかに例外をスローし、そして40は煙に上がる前に引退の私の夢。

質問:どのようにWCFをDIでうまく演奏させて、OperationContextをラップするのですか?

答えて

1

OperationContext.Currentは、設定可能なプロパティです。テストの初期化を

OperationContext.Current = new OperationContextWrapper(); 

に変更することはできますか?あなたが団結して、それを必要とする場合は、あなたもできます

var oc = new OperationContextWrapper(); 
OperationContext.Current = oc; 
container.RegisterInstance<IOperationContext>(oc); 
+0

しかし、あなたのようにそれを呼び出しますので、この場合には、OperationContextWrapperは、OperationContext.Currentの周りに巻かれる:OperationContextWrapperコンテキスト=新しいOperationContextWrapper(OperationContext.Current)。これはおおよそ私のUnityコードが達成しようとしているものです。 –

+2

最後に、私はOperationContextWrapperで貧乏人のDIを使用し、OperationContext.Currentをより一般的なコンストラクタに挿入したデフォルトのコンストラクタを作成し、依存性を持つコンストラクタではなくデフォルトコンストラクタを使用するようにUnityに指示しました。今サービスはうまく起動し、実行時にはOperationContext.Currentを使用し、ユニットテストではモックオブジェクトを使用します。 –

2

は、たぶん私は理解しないんだけど、あなたがラッパーにOperationContext.Currentを注入する理由私はわかりません。もしOperationContextWrapperがOperationContextをラッピングしているのであれば、なぜそれが実装されているのではなく、OperationContext.Currentと直接対話する必要があるのですか?私はあなたがテスト可能なままにしようとしているコードは、OperationContextWrapperではなく、IOperationContextインタフェースを介してそれに依存するコードであると推測します。次に、誰がOperationContextWrapperが何をしているかを気にしますか?

1

また、Microsoftの偽物を使用することができます。

using (ShimsContext.Create()) 
{ 
ShimOperationContext shimOperationContext = new 
ShimOperationContext(); shimOperationContext.SessionIdGet =() => "sessionId"; 

OperationContext.Current = shimOperationContext; 
} 
関連する問題