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.
> Global.asax.cs:http://pastebin.com/437Tnp0t
> web.config:http://pastebin.com/5pU6SH6c
请注意,CustomActionFilter注册为全局过滤器,因此它使用autofac注册:
public class FilterConfig { public static void RegisterGlobalFilters(GlobalFilterCollection filters) { filters.Add(new HandleErrorAttribute()); filters.Add(DependencyResolver.Current.GetService<CustomActionFilter>()); } }
我试过了:
>为MVC和Web.Forms使用单独的容器 – 结果相同
>使用属性注入而不是构造函数 – 结果相同
>在web.forms页面上显式触发依赖关系解析(如this) – 工作
所以,问题是,有没有办法为MVC和web.forms部分提供幕后依赖解析.我是autofac的新手,对于一般的依赖注入容器来说有点新,所以我可能会错过一些明显的东西.
解决方法
错误#1:作为修复Issue 351的副作用,AutofacDependencyResolver需要在创建的Request绑定LifeTimeScopes中注册. MVC集成做到了这一点,但Winforms集成当然没有.
错误? #2:RequestLifetimeScopeProvider和ContainerProvider都使用相同的密钥HttpContext.Current.Items存储创建的ILifetimeScope:
static ILifetimeScope LifetimeScope { get { return (ILifetimeScope)HttpContext.Current.Items[typeof(ILifetimeScope)]; } set { HttpContext.Current.Items[typeof(ILifetimeScope)] = value; } }
所以这里有一点竞争条件,因为取决于首先执行哪个模块,WebForms或MVC intergartion ILifetimeScope获胜.因此,如果WebForms模块获胜,则AutofacDependencyResolver将不会被注册,并且您将获得良好的非描述性异常.
修复/解决方法:
但是有一个简单的解决方法:您只需要在ContainerProvider requestLifetimeConfiguration中注册AutofacDependencyResolver,因此无论哪一个获胜(WebForm与MVC),AutofacDependencyResolver将始终注册:
var autofacDependencyResolver = new AutofacDependencyResolver(container); DependencyResolver.SetResolver(autofacDependencyResolver); _containerProvider = new ContainerProvider(container,requestContainerBuilder => requestContainerBuilder.RegisterInstance(autofacDependencyResolver) .As<AutofacDependencyResolver>());