2013-08-20 22 views
6

私は、MVCに部分的に書き直された従来のWeb.Formsアプリケーションを持っています。 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の自動ファクシミリの統合を使用しようとすると、に関連するNullReferenceExceptionがautofacの内部(stack trace)のどこかにあります。

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

私は試しました:

    同じ結果代わりコンストラクタの
  1. 使用プロパティインジェクション - - 同じ結果
  2. が明示的(thisなど)web.formsページの依存関係の解決をトリガ - MVCとWeb.Formsための別々の容器を用いて

働いしたがって、問題は、MVCとweb.formsの両方のパートの背後にある依存関係解決を提供する方法があることです。私はオートファックには新しく、一般的には依存性注入容器に少し新しかったので、明らかに何かを見逃すかもしれません。

更新:エラーは、カスタムフィルタとは関係ありません。カスタムフィルタへの参照をすべて削除しても、バグの振る舞いはスタックトレースでも同じです。

+0

あなたが 'ContainerDisposalModule'をコメントアウトした後、' PropertyInjectionModule'と 'AttributedInjectionModule'を再び有効にするとどうなりますか? Autofac.MVCにはリクエスト中に作成されたLifetimscopeを廃棄する新しい 'RequestLifetimeHttpModule'が含まれているため、' ContainerDisposalModule'は必要ありません。 – nemesv

+0

@nemesv同じ結果。 – J0HN

+0

OK、問題が何であるか分かります。あなたは 'InstancePerHttpRequest'で登録されたサービスを持っていますか? – nemesv

答えて

6

実際には2つのバグがありますか? Autofacでこの動作を引き起こしている:

バグ#1:Issue 351の修正の副作用としてLifeTimeScopeのバインド作成要求に登録するAutofacDependencyResolverニーズが。 MVCの統合はこれを行いますが、Winformsの統合はもちろんありません。

バグ? #2:RequestLifetimeScopeProviderContainerProvider店が同じキーHttpContext.Current.ItemsILifetimeScopeを作成両方:

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

最初のWebフォームまたはMVC intergartionを実行されますによってどのモジュールにするのでだから、少しの競合状態がここにありますILifetimeScopeが勝ちます。したがって、WebFormsモジュールが勝利した場合、AutofacDependencyResolverは登録されず、優れた記述的な例外が発生します。

修正/回避策:

しかし、簡単な回避策があります:あなたはちょうどそうに関係なく1勝(MVC対Webフォームが)AutofacDependencyResolverは常に登録されますContainerProviderrequestLifetimeConfigurationAutofacDependencyResolverを登録する必要があります:

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

魅力的な作品です、ありがとうございました。 – J0HN

関連する問題