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

梦想与她 提交于 2019-12-10 04:33:49

问题


I've got a legacy Web.Forms app that been partially rewritten to MVC. MVC part uses autofac as a dependency injection container.

MVC part have custom filter defined:

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 fine when Web.Forms integration is disabled in web.config. Hovewer, when I try to use Web.Forms autofac integration, I've got the NullReferenceException related to AutofacFilterProvider somewhere in autofac internals (stack trace).

  • Global.asax.cs: http://pastebin.com/437Tnp0t
  • web.config: http://pastebin.com/5pU6SH6c

Note that CustomActionFilter is registered as global filter, thus it is registered with autofac:

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

I've tried:

  1. using separate containers for MVC and Web.Forms - same result
  2. Use property injection instead of constructor - same result
  3. Explicitly trigger dependencies resolution on web.forms pages (like this) - worked

So, the question is, are there any way to provide behind-the-scenes dependency resolution both to MVC and web.forms part. I'm new to autofac and somewhat new to dependency injection containers in general, so I might just miss something obvious.

Update: error has nothing to do with custom filters. If I remove all references to custom filters the bug behavior still the same, even the stack trace.


回答1:


Actually there are two bugs? in Autofac which causing this behavior:

Bug #1: As side effect of the fix of Issue 351 the AutofacDependencyResolver needs to registered in the created Request bound LifeTimeScopes. The MVC intergration does this but the Winforms integration of course does not.

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

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

So there is a little bit race condition here because depending on which module gets executed first the WebForms or the MVC intergartion ILifetimeScope wins. So if the WebForms module wins the AutofacDependencyResolver won't be registered and you get the nice non descriptive exception.

Fix/workaround:

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

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


来源:https://stackoverflow.com/questions/18340594/autofac-mvc-with-actionfilters-web-forms-dependency-resolution-conflict

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!