2

IoC コンテナー (autofac) の RequestContext を登録しようとしています。すべての登録は Application_start で行います。

RequestContext の登録は次のようになります。

builder.Register(x => HttpContext.Current.Request.RequestContext).As<RequestContext>();

これは開発 Web サーバーでは問題なく動作しますが、IIS 7 (統合モード) では、RequestContext コンテキストが Application_start で利用できないことが問題です。

ここで何ができますか?

4

1 に答える 1

5

ここで解決すべき 2 つの問題があるようです。

  1. RequestContext をどのように登録しますか?
  2. RequestContext が適切に解決されないのはなぜですか?

Autofac MVC 統合を使用している場合、登録のためにできる最も簡単なことは次のとおりです。

builder.RegisterModule<AutofacWebTypesModule>();

instance-per-HTTP-request に適切にスコープされたさまざまな Web 抽象化 (HttpContextBase、RequestContext など) を登録するモジュールが既に存在します。テスト済みで、多くの時間を節約できます。

代わりに、自分で手動で登録したい場合は、 InstancePerHttpRequest に範囲を指定すると、必要なことを行うことができます (そうすれば、リクエストごとに何度も取得することはありません)。

さらに、モジュールのように現在のコンテキストに「チェーン」できます。

builder.Register(c => new HttpContextWrapper(HttpContext.Current))
    .As<HttpContextBase>()
    .InstancePerHttpRequest();
builder.Register(c => c.Resolve<HttpRequestBase>().RequestContext)
    .As<RequestContext>()
    .InstancePerHttpRequest();

これで最初の部分は処理できますが、2 番目の部分はややこしいです。

RequestContext が利用できないためにアプリの起動時にエラーが発生する場合は、実際にリクエストを受け取る前に、アプリのどこかで RequestContext を使用する何かを解決しようとしています。たとえば、コンストラクター パラメーターとして RequestContext を持つ何かを手動で解決しようとする HttpModule 実装。

登録のラムダは実際には解決されるまで評価されないため、エラーはおそらく、解決しようとしているものが RequestContext をあまりにも早く消費しようとしていることに起因しています。

その場合、質問は次のとおりです: RequestContext を解決しようとして、リクエストがない場合、解決をどのように処理しますか?

デフォルトでは例外が発生しますが、これはおそらく現在表示されているものです。

代わりに null にしたい場合は、次のように登録します。

// Register context as instance-per-dependency and handle the
// case where it's null. Also handle HttpException because IIS7
// can throw if you access HttpContext.Current too soon in app startup.
builder.Register(
  c => {
    try
    {
      var ctx = HttpContext.Current;
      return ctx == null ? null : new HttpContextWrapper(ctx);
    }
    catch(HttpException)
    {
      return null;
    }
  }).As<HttpContextBase>();

// RequestContext also gets registered instance-per-dependency
// and handles the null context case.
builder.Register(
  c => {
    var ctx = c.Resolve<HttpRequestBase>();
    return ctx == null ? null : ctx.RequestContext;
  }).As<RequestContext>();

これにより、アプリの起動の問題を回避できます。

つまり、アプリケーションの起動時に RequestContext を使用しようとしている原因を突き止め、設計を修正できるかどうかを確認する必要があります。通常の状況では、この種のことを行う必要はありません。

于 2012-06-08T15:53:56.867 に答える