2013-08-20 62 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