1

私はhttpリクエストをトレースするカスタムHttpModuleを持っていますが、実装の一部は以下の通りです。HttpModuleへのコンストラクタインジェクションを使用してHttpContextを注入していますか?

private readonly HttpContextBase _httpContext; 
    private readonly ISessionContext _sessionContext; 

    public ASHttpModule(HttpContextBase httpContext, 
     ISessionContext sessionContext) 
    { 
     this._httpContext = httpContext; 
     this._sessionContext = sessionContext; 
    } 
    public void Init(HttpApplication context) 
    { 
     context.BeginRequest += Context_BeginRequest; 
     context.EndRequest += Context_EndRequest; 
    } 
    private void Context_BeginRequest(object sender, EventArgs e) 
    { 
     Stopwatch stopwatch = new Stopwatch(); 
     _httpContext.Items["Stopwatch"] = stopwatch; 
     stopwatch.Start(); 
    } 
    private void Context_EndRequest(object sender, EventArgs e) 
    { 
      Stopwatch stopwatch = (Stopwatch)_httpContext.Items["Stopwatch"]; 
      if (stopwatch == null) 
       return; 

      stopwatch.Stop(); 
      TimeSpan ts = stopwatch.Elapsed; 
      //Check current httprequest variables and log if have to 

    } 

ここで私の依存関係の登録(Autofacを使用)。

 builder.RegisterType<WebSessionContext>() 
      .As<ISessionContext>().InstancePerRequest(); 
     builder.Register(c => (new HttpContextWrapper(HttpContext.Current) as HttpContextBase)) 
      .As<HttpContextBase>() 
      .InstancePerRequest(); 
     builder.Register(c => c.Resolve<HttpContextBase>().Request) 
      .As<HttpRequestBase>() 
      .InstancePerRequest(); 
     builder.Register(c => c.Resolve<HttpContextBase>().Server) 
      .As<HttpServerUtilityBase>() 
      .InstancePerRequest(); 
     builder.Register(c => c.Resolve<HttpContextBase>().Session) 
      .As<HttpSessionStateBase>() 
      .InstancePerRequest(); 

問題は、ここでのHttpContextが要求ごとに注入する必要がありながら、HttpModuleを一度だけ構成されています。私が見つけたソリューションは、DependencyResolverを次のように使用しています。

 HttpContextBase _httpContext = DependencyResolver.Current.GetService<HttpContextBase>(); 

ただし、ServiceLocatorはアンチパターンと見なされますので、この使用を避けたいと思います。

DependencyResolverを使用せずにHttpContextをHttpModuleに挿入する方法はありますか?

+0

→問題の原因をあざけるあなたは[あなたのコンポーネントにランタイムデータ]を注入していることである/テスト(https://www.cuttingedge.it/blogs/steven/pivot/entry.php?id=99)。 – Steven

+1

ブログの投稿をありがとう。私の間違いを見るのを助けました。エレガントなソリューション。 –

答えて

2

あなたは正しいのHttpContextインスタンスを取得するファクトリを使用しようとすることができます:

private readonly Func<HttpContextBase> _httpContextFactory; 
private readonly ISessionContext _sessionContext; 

public ASHttpModule(Func<HttpContextBase> httpContextFactory, 
    ISessionContext sessionContext) 
{ 
    this._httpContextFactory = httpContextFactory; 
    this._sessionContext = sessionContext; 
} 
private void Context_BeginRequest(object sender, EventArgs e) 
{ 
    var httpContext = this._httpContextFactory(); 
    Stopwatch stopwatch = new Stopwatch(); 
    httpContext.Items["Stopwatch"] = stopwatch; 
    stopwatch.Start(); 
} 

私はAutofacがあまりにもFunc`1インスタンスを注入することができると仮定します。そうでない場合は、HttpContextのファクトリとして機能する単純なクラスを作成する必要があります。

次に、あなたが注入することができ:

  • 通常の動作→() => HttpContextWrapper(HttpContext.Current)
  • ここ() => new HttpContextMock()
+0

スティーブンスのブログ記事のように、工場を使うことは解決策の1つです。私は、ソリューションstevenの提供は、より合理的な響きと思う、私はそれと一緒に行くだろう。とにかくありがとう。 –

+0

2番目の考えでは、実際にはこれも良い解決策です。 –

関連する問題