Autofac, MVC (with ActionFilters), Web.Forms - dependency resolution conflict

I have an outdated Web.Forms application that is partially rewritten in MVC. Part of MVC uses autofac as a container for dependency injection.

The MVC part has a custom filter:

public class CustomActionFilter : ActionFilterAttribute { protected ILogger Logger { get; set; } public CustomActionFilter(ILogger logger) { Logger = logger; } public override void OnActionExecuting(ActionExecutingContext filterContext) { Logger.Log("OnActionExecuting"); } } 

It works great when Web.Forms integration is disabled in web.config. Hovewer, when I try to use integration with autofac Web.Forms, I have a NullReferenceException that is related to AutofacFilterProvider somewhere inside autofac internals ( stack trace ).

Note that CustomActionFilter registered as a global filter, so it is registered using autofac:

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

I tried:

  • using separate containers for MVC and Web.Forms - same result
  • Use property injection instead of constructor - same result
  • Explicitly run dependency resolution on web.forms pages (e.g. this ) - worked

So, the question is, is there a way to provide a capital dependency dependency with both MVC and the web.forms part. I am new to autofac and a few new dependency injection containers, so I could just skip something obvious.

Update: The error has nothing to do with custom filters. If I remove all links to user filters, the error behavior will remain unchanged, even the stack trace.

+6
source share
1 answer

Actually there are two errors? in Autofac that cause this behavior:

Mistake # 1: As a side effect of fixing Problem 351 AutofacDependencyResolver needs to be registered in the generated LifeTimeScope s request. MVC interaction does this, but Winforms integration certainly does not.

error? # 2: Both RequestLifetimeScopeProvider and ContainerProvider save the created ILifetimeScope with the same HttpContext.Current.Items key:

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

So, there is a bit of a race condition, because depending on which module will be executed, WebForms or MVC Intergartion ILifetimeScope first wins. Therefore, if the WebForms module wins the AutofacDependencyResolver , it will not be registered, and you will get a beautiful exception exception.

Fix / workaround:

But there is a simple workaround: you just need to register the AutofacDependencyResolver in the ContainerProvider requestLifetimeConfiguration , so no matter which one wins (WebForm vs. MVC), AutofacDependencyResolver will always be registered:

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

Source: https://habr.com/ru/post/952131/


All Articles