Autofac,MVC(带ActionFilters),Web.Forms - 依赖解析冲突

时间:2013-08-20 16:44:11

标签: asp.net-mvc webforms autofac

我有一个遗留的Web.Forms应用程序被部分重写为MVC。 MVC部分使用autofac作为依赖注入容器。

MVC部分定义了自定义过滤器:

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

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

在web.config中禁用Web.Forms集成时,它可以正常工作。 Hovewer,当我尝试使用Web.Forms autofac集成时,我在autofac内部(stack trace)的某个地方得到了与AutofacFilterProvider相关的NullReferenceException。

请注意,CustomActionFilter已注册为全局过滤器,因此已使用autofac注册:

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

我试过了:

  1. 为MVC和Web.Forms使用单独的容器 - 结果相同
  2. 使用属性注入而不是构造函数 - 结果相同
  3. 在web.forms页面上显式触发依赖关系解析(如this) - 工作
  4. 所以,问题是,有没有办法为MVC和web.forms部分提供幕后依赖解析。我是autofac的新手,对一般的依赖注入容器来说有点新,所以我可能会错过一些明显的东西。

    更新:错误与自定义过滤器无关。如果删除对自定义过滤器的所有引用,则错误行为仍然相同,甚至是堆栈跟踪。

1 个答案:

答案 0 :(得分:6)

实际上有两个错误?在Autofac中导致此行为:

错误#1:由于Issue 351修复的副作用,AutofacDependencyResolver需要在创建的请求绑定LifeTimeScope中注册。 MVC集成可以做到这一点,但Winforms集成当然不会。

<强>错误? #2: RequestLifetimeScopeProviderContainerProvider都将创建的ILifetimeScope存储为相同的密钥HttpContext.Current.Items

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

所以这里有一点竞争条件,因为取决于首先执行哪个模块,WebForms或MVC intergartion ILifetimeScope获胜。因此,如果WebForms模块获胜,则AutofacDependencyResolver将不会被注册,并且您将获得良好的非描述性异常。

<强>修复/解决方法:

但是有一个简单的解决方法:您只需要在AutofacDependencyResolver ContainerProvider中注册requestLifetimeConfiguration,这样无论哪一个获胜(WebForm与MVC){{1}将永远注册:

AutofacDependencyResolver