1

http isteklerini izlediğim özel bir HttpModule'im var, uygulamanın bir kısmı aşağıdaki gibidir;HttpModule'a constructor enjeksiyonu kullanarak HttpContext'i mi kullanıyorsunuz?

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 

    } 

Burada benim bağımlılık kaydı (Autofac kullanarak);

 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(); 

Sorun burada HttpContext her istek için enjekte edilmesi gerekmektedir ederken HttpModule'ü sadece bir kez inşa olmasıdır. Bulduğum çözüm, DependencyResolver uygulamasını aşağıdaki gibi kullanıyor:

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

Ancak, ServiceLocator anti-pattern olarak kabul edildiğinden bu kullanımdan kaçınmak istiyorum.

HttpContext'in HttpModule'a DependencyResolver kullanmadan enjekte edilmesi için herhangi bir çözüm var mı?

+0

→ sorunun kaynağını alay sen [senin bileşenlerine çalışma zamanı verilerini] enjekte olmasıdır/test (https://www.cuttingedge.it/blogs/steven/pivot/entry.php?id=99). – Steven

+1

Blog yayını için teşekkürler. Hatamı görmeme yardımcı oldu. Zarif bir çözüm. –

cevap

2

Doğru HttpContext örneğini almak için bir fabrika kullanmayı deneyebilirsiniz:

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(); 
} 

Ben Autofac çok Func`1 örneklerini enjekte varsayalım. Değilse, HttpContext'iniz için fabrika olarak çalışan basit bir sınıf oluşturmanız gerekebilir.

Sonra enjekte edebilir

  • Normal işletim → () => HttpContextWrapper(HttpContext.Current)
  • burada () => new HttpContextMock()
+0

Fabrikadan yararlanmak, Stevens blog yazısının dediği çözümlerden biridir. Ben steven çözümün daha mantıklı olduğunu düşünüyorum ve bununla birlikte gideceğim. Yine de teşekkürler. –

+0

İkinci bir düşüncede, aslında bu da iyi bir çözüm. –