2013-08-20 8 views
6

Ho un'app legacy Web.Forms che è stata parzialmente riscritta su MVC. La parte MVC utilizza autofac come contenitore di iniezione delle dipendenze.Autofac, MVC (con ActionFilters), Web.Forms - conflitto di risoluzione delle dipendenze

MVC parte hanno filtro personalizzato definito:

public class CustomActionFilter : ActionFilterAttribute 
{ 
    protected ILogger Logger { get; set; } 
    public CustomActionFilter(ILogger logger) { Logger = logger; } 

    public override void OnActionExecuting(ActionExecutingContext filterContext) 
    { 
     Logger.Log("OnActionExecuting"); 
    } 
} 

Funziona bene quando l'integrazione Web.Forms è disattivato nel web.config. Hovewer, quando provo a utilizzare l'integrazione autofac di Web.Forms, ho ottenuto l'eccezione NullReferenceException relativa a AutofacFilterProvider da qualche parte negli interni di autofac (stack trace).

noti che CustomActionFilter è registrato come filtro globale, quindi è iscritto su autofac:

public class FilterConfig 
{ 
    public static void RegisterGlobalFilters(GlobalFilterCollection filters) 
    { 
     filters.Add(new HandleErrorAttribute()); 
     filters.Add(DependencyResolver.Current.GetService<CustomActionFilter>()); 
    } 
} 

Ho provato:

  1. utilizzando contenitori separati per MVC e Web.Forms - stesso risultato
  2. l'iniezione di proprietà invece di constructor - stesso risultato
  3. esplicitamente innescare risoluzione dipendenze sulle pagine web.forms (come this) - ha lavorato

Quindi, la domanda è: esiste un modo per fornire una risoluzione delle dipendenze dietro le quinte sia per la parte MVC che per quella web.forms. Sono nuovo di autofac e in qualche modo nuovo per i contenitori di iniezione di dipendenza in generale, quindi potrei semplicemente perdere qualcosa di ovvio.

Aggiornamento: errore non ha nulla a che fare con i filtri personalizzati. Se rimuovo tutti i riferimenti ai filtri personalizzati, il comportamento degli errori è sempre lo stesso, anche la traccia dello stack.

+0

che cosa succede se si commento la 'ContainerDisposalModule' e dopo che si riattivare' 'PropertyInjectionModule' e AttributedInjectionModule'? Il 'ContainerDisposalModule' non dovrebbe essere necessario perché Autofac.MVC include un nuovo' RequestLifetimeHttpModule' che dispone il Lifetimscope creato durante la richiesta ... – nemesv

+0

@nemesv stesso risultato. – J0HN

+0

OK, vedo ora qual è il problema ... avrete servizi registrati con 'InstancePerHttpRequest'? – nemesv

risposta

6

In realtà ci sono due bug? in Autofac che causano questo comportamento:

Bug # 1: Come effetto collaterale della correzione dei Issue 351 le AutofacDependencyResolver esigenze per iscritto nella Richiesta creato legato LifeTimeScope s. L'integrazione MVC fa questo, ma l'integrazione di Winforms ovviamente non lo fa.

Errore? # 2: Sia il RequestLifetimeScopeProvider ei ContainerProvider memorizza il creato ILifetimeScope con la stessa chiave HttpContext.Current.Items:

static ILifetimeScope LifetimeScope 
{ 
    get { return (ILifetimeScope)HttpContext.Current.Items[typeof(ILifetimeScope)]; } 
    set { HttpContext.Current.Items[typeof(ILifetimeScope)] = value; } 
} 

Quindi c'è un po 'di condizione di punta gara qui, perché a seconda di quale modulo viene eseguito prima le WebForms o intergartion MVC Vince ILifetimeScope. Quindi, se il modulo WebForms vince, lo AutofacDependencyResolver non sarà registrato e otterrai la bella eccezione non descrittiva.

Fix/soluzione:

Ma c'è una soluzione semplice: è sufficiente registrare il AutofacDependencyResolver nel ContainerProviderrequestLifetimeConfiguration quindi non importa che uno vince (WebForm vs MVC) il AutofacDependencyResolver sarà sempre registrata :

var autofacDependencyResolver = new AutofacDependencyResolver(container); 
DependencyResolver.SetResolver(autofacDependencyResolver); 
_containerProvider = new ContainerProvider(container, requestContainerBuilder => 
    requestContainerBuilder.RegisterInstance(autofacDependencyResolver) 
    .As<AutofacDependencyResolver>()); 
+0

Funziona come un incantesimo, grazie mille. – J0HN