2012-05-25 12 views
7

Ésta es una aplicación Asp.net (no MVC) que se ejecuta Net 3.5como registrar HttpContextBase con Autofac en Asp.Net (no MVC)

lo hice:

protected void Application_Start(object sender, EventArgs e) 
{ 

... 

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

Pero Doesn no funciona

El error que estoy haciendo esto:

No se alcance con una etiqueta a juego 'httpRequest' es visible desde el ámbito en el que se pidió a la instancia. Esto generalmente indica que un componente registrado como solicitud por HTTP está siendo solicitado por un componente SingleInstance() (o un escenario similar). Bajo la integración web, siempre solicite dependencias de DependencyResolver.Current o ILifetimeScopeProvider.RequestLifetime, nunca del contenedor en sí. .

Entonces me encontré esto: https://stackoverflow.com/a/7821781/305469

Y lo hice esta vez:

 builder.Register(c => new HttpContextWrapper(HttpContext.Current)) 
      .As<HttpContextBase>() 
      .InstancePerLifetimeScope(); 

Pero ahora cuando hago esto:

public class HttpService : IHttpService 
{ 
    private readonly HttpContextBase context; 

    public HttpService(HttpContextBase context) 
    { 
     this.context = context; 
    } 

    public void ResponseRedirect(string url) 
    { 
     //Throws null ref exception 
     context.Response.Redirect(url); 
    } 
} 

y me dieron una excepción nula de referencia .

Extrañamente, context.Response no es nulo, es cuando llamo .Redirect() que arroja.

Me pregunto si está usando .InstancePerLifetimeScope(); es el problema.

Por cierto, intenté usar Response.Redirect() y funciona perfectamente.

¿Cuál podría ser el problema?

Gracias,

Chi

+1

En su primer ejemplo con 'InstancePerHttpRequest', ¿qué significa: no funciona? Excepción, etc.? ¿Y cómo resuelve su 'HttpService' o cómo está registrado? Cuando mencionó la excepción de ref nula, ¿cuál es la stacktrace completa? – nemesv

+0

Como dijo nemesv, ¿por qué no funciona la versión .InstancePerHttpRequest()? – codeulike

+0

Gracias chicos, he actualizado la pregunta para incluir el error que estaba recibiendo cuando uso .InstancePerHttpRequest() –

Respuesta

4

Parece que su clase HttpService puede estar registrada como un componente SingleInstance() (singleton). O bien, una de las clases que tiene IHttpService como dependencia es un singleton.

Cuando esto ocurre, a pesar de que haya configurado Autofac devolver una nueva instancia por HttpContextBase petición HTTP (o alcance toda la vida, que también es correcto) la clase HttpService se aferran a lo que era HttpContextBase corriente cuando la única HttpService instancia fue creada.

Para probar esta teoría, intente tomar una dependencia en HttpContextBase directamente desde una página y vea si el problema persiste. Averiguar cuál es el componente singleton debería ser bastante sencillo si es así.

+0

¡Esto es exactamente lo que hice! El HttpService y otros servicios que llaman HttpService están registrados como Singletons. Gracias por su ayuda, Nicholas. –

+0

@ChiChan según la respuesta y su comentario anterior, ¿qué cambió para que funcione? ¿Cambiaste el tiempo de vida/alcance de HttpService a algo que no sea Singleton? – Stokedout

+0

@Stokedout, sí, fue hace un tiempo, pero terminé convirtiendo el registro único de HttpService en otro ámbito. –

0

Registro HttpContextWrapper con un alcance de por vida es como usar registerInstance(), es decir, siempre se va a utilizar la misma instancia de HttContextWrapper. Por lo tanto, la segunda solicitud utilizará el HttpContext de la primera solicitud, lo que generará un error extraño.

Posible solución alternativa: crear su propia envoltura para HttpContext y registrarlo con la instancia de tiempo de vida y dejar que se utilice el HttpContext corriente interna:

public interface IMyWrapper 
{ 
    void ResponseRedirect(string url); 
} 

public class MyWrapper : IMyWrapper 
{ 
    public void ResponseRedirect(string url) 
    { 
     HttpContext.Current.Response.Redirect(url); 
    } 
} 

builder.Register(c => new MyWrapper()) 
    .As<IWrapper>() 
    .InstancePerLifetimeScope(); 

De esta manera no se inyecta el HttpContext, aunque . No estoy seguro si eso es importante ...

+0

¡Gracias! Esta solución funcionaría y es lo que tengo actualmente, pero todavía me pregunto si hay una forma de registrar pacíficamente el contexto dentro de Autofac. –

Cuestiones relacionadas