私はいくつかのWebForms / MVCに依存しないツールを使用しておりHttpContext、HttpContextBaseオブジェクトへの参照が指定されているインスタンスを取得する必要があります。HttpContext.Currentこれも非同期で動作する必要があるため、使用できません(非同期要求中にHttpContext.Current戻りますnull)。は承知してHttpContextWrapperいますが、間違った方向に進んでいます。
私はいくつかのWebForms / MVCに依存しないツールを使用しておりHttpContext、HttpContextBaseオブジェクトへの参照が指定されているインスタンスを取得する必要があります。HttpContext.Currentこれも非同期で動作する必要があるため、使用できません(非同期要求中にHttpContext.Current戻りますnull)。は承知してHttpContextWrapperいますが、間違った方向に進んでいます。
回答:
最も簡単な方法は、アプリケーションを取得し、ApplicationInstanceそのContextプロパティを使用することです。
// httpContextBase is of type HttpContextBase
HttpContext context = httpContextBase.ApplicationInstance.Context;
(コメントでこれを指摘したIshmael Smyrnowに感謝)
特に、HttpContextBase渡されたインスタンスがHttpContextWrapper実行時のタイプである場合は可能です。次の例は、これを行う方法を示しています。Fooコンテキストを受け入れるメソッドが呼び出されたHttpContextBaseが、コンテキストがと入力されていることを期待しているサードパーティアセンブリ(変更する幸運がない可能性がある)のメソッドを呼び出す必要があるとしますHttpContext。
void Foo(HttpContextBase context)
{
var app = (HttpApplication) context.GetService(typeof(HttpApplication));
ThirdParty.Bar.Baz(app.Context);
}
// Somewhere in assembly and namespace ThirdParty,
// in a class called Bar, there is Baz expecting HttpContext:
static void Baz(HttpContext context) { /* ... */ }
HttpContextBaseGetServiceサポートの結果として呼び出されるメソッドがありIServiceProviderます。ラップされたインスタンスの実装へGetServiceのHttpContextWrapperデリゲートのオーバーライド。実装は、のような通常の容疑者のクエリにあなたを可能にする、、のように。たまたま、Contextというプロパティがあり、のインスタンスを返す場合があります。そのため、viaを要求し、続いて返されたインスタンスのプロパティを読み取ることで、ラップされたインスタンスを取得します。GetServiceHttpContextGetServiceHttpContextHttpApplicationHttpRequestHttpResponseHttpApplicationHttpContextHttpContextHttpContextBaseHttpApplicationGetServiceContextHttpApplication
とは異なりHttpContextBase、GetServiceはのパブリックメンバーとしては表示されませんHttpContextが、は明示的にをHttpContext実装しているのに、IServiceProvider.GetService明示的にHttpContextBaseは実装していないためです。
これは、テスト中Fooに基HttpContextになるものをアンラップできることに依存しており、そもそも偽造/スタブすることがほぼ不可能であるため、もはやテスト不可能であることを覚えておいてください。ただし、この回答の要点は、文字通り「HttpContextBaseからHttpContextオブジェクトを取得するにはどうすればよいですか?」という質問に対処することです。図示されている手法は、必ずしもコンポーネントを変更する余裕がないコンポーネントに挟まれている状況で役立ちます。
context.ApplicationInstance.Contextか?
Http*Baseによって返されたすべてのバリエーションの中でそれを逃したことはありませんHttpContextBase。:P答えを更新します。
あなたはできる、
var abstractContext = new System.Web.HttpContextWrapper(System.Web.HttpContext.Current);
できません。
の全体的な目的はHttpContextBase、具象HttpContextクラスへの依存関係を抽象化することです。これには具象が含まれている場合がありますがHttpContext (の場合などhttpContextWrapper)、他の実装ではまったく関係がない場合がありHttpContextます。
HttpContextBase常に具象をHttpContextでラップできるため、最適なオプションは、を取得できるカスタムの抽象ファクトリを定義することですHttpContextWrapper。
IHttpHandler実装をテストするには、ユニットテストのために(応答ラッパー)に抽象化の敷居数を配置する必要がありますが、これは正しくないように思われますが、唯一の選択肢となります。