2013-08-20 32 views
6

我有一个遗留的Web.Forms应用程序被部分重写为MVC。 MVC部分使用autofac作为依赖注入容器。Autofac,MVC(带有ActionFilters),Web.Forms - 依赖关系解析冲突

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.Forms集成在web.config中被禁用,它工作正常。 Hovewer,当我尝试使用Web.Forms autofac集成时,我在NullReferenceException中遇到了有关AutofacFilterProvider在autofac内部(stack trace)中的某处。

注意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) - 工作

所以,问题是,有没有办法为MVC和web.forms部分提供幕后依赖解析。我是新来的autofac和一般的依赖注入容器有点新,所以我可能会错过一些明显的东西。

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

+0

如果您注释掉'ContainerDisposalModule'并且之后重新启用'PropertyInjectionModule'和'AttributedInjectionModule',会发生什么? 'ContainerDisposalModule'不应该被需要,因为Autofac.MVC包含一个新的'RequestLifetimeHttpModule',这个'RequestLifetimeHttpModule'放置了请求期间创建的Lifetimscope ... – nemesv

+0

@nemesv同样的结果。 – J0HN

+0

好吧,我现在看到了什么问题......你有服务注册'InstancePerHttpRequest'吗? – nemesv

回答

6

其实有两个错误?在Autofac其中引起此行为:

错误#1:Issue 351AutofacDependencyResolver需要在结合LifeTimeScope S中的创建请求注册的修复程序的作为副作用。 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; } 
} 

所以有一点点竞争条件在这里,因为这取决于模块中最先被执行的Web窗体或MVC intergartion ILifetimeScope获胜。因此,如果WebForms模块赢得AutofacDependencyResolver将不会被注册,并且您会得到很好的非描述性异常。

修复/解决办法:

但有一个简单的解决方法:你只需要注册在ContainerProviderrequestLifetimeConfiguration所以无论是哪一个胜场(主场迎战的WebForm MVC)的AutofacDependencyResolver将始终注册AutofacDependencyResolver

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

工程就像一个魅力,非常感谢你。 – J0HN