17

短い質問:この未回答の問題と同じ

長い質問:

Autofacを使用していたMVC 4 + Web Apiソリューションから、Autofacを使用しているがWeb Api 2のみを使用している新しいソリューションにいくつかのコードを移植しました(MVC 5.1プロジェクトではなく、Web APIのみ)。

以前のソリューションでは、MVC4 と Web Api があったため、それぞれに 1 つずつ、2 つの Bootstrapper.cs ファイルがありました。新しいプロジェクトの Web Api ブートストラップだけをコピーしました。

現在、新しいソリューションには、依存関係をプルする必要がある 2 つのプロジェクトがあります。DependencyResolver.Current.GetService<T>()アンチパターンであるにもかかわらず、使用する必要があると仮定しましょう。

最初は、MVC 依存関係リゾルバーを同じコンテナーに設定するまで、これは機能しませんでした:

GlobalConfiguration.Configuration.DependencyResolver = 
     new AutofacWebApiDependencyResolver(container);

//I had to pull in Autofac.Mvc and Mvc 5.1 integration but this line fixed it
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));

奇妙な部分は、それらのプロジェクトの 1 つだけで修正されたことです。状況は次のとおりです。

 Solution.Web project
      Bootstrapper.cs that registers both dependency resolvers for web api and mvc.

 Solution.ClassLib project
      var userRepo = DependencyResolver.Current.GetService<IUserRepo>(); //Good! :)

 Solution.WindowsWorkflow project
      var userRepo = DependencyResolver.Current.GetService<IUserRepo>(); //Throws exception :(

例外は次のとおりです。HttpContext が使用できないため、要求の有効期間スコープを作成できません。

ワークフローのせいにする前に、ワークフローが DependencyResolver をうまく使用できた別のソリューションで、この正確な設定がうまく機能していたことを知っておいてください。したがって、これはAutofacの新しいバージョンの使用と、ワークフローが非同期で実行されるという事実に関係していると思われます(非同期コードに関してリンクした質問と同じように)

InstancePerLifetimeScope()代わりに使用するすべての登録コードを切り替えてInstancePerHttpRequest()、スコープを作成しようとしました:

using (var c= AutofacDependencyResolver.Current
                     .ApplicationContainer.BeginLifetimeScope("AutofacWebRequest"))
{
   var userRepo = DependencyResolver.Current.GetServices<IUserRepo>();
}

しかし、それは例外を変更しませんでした。コードをさらに分解すると、正確な犯人は次のとおりです。

var adr = AutofacDependencyResolver.Current; //Throws that exception 

これを乗り越える必要があり、立ち往生する時間がかかりすぎました。2 日以内に既存の回答に報奨金が与えられます

4

4 に答える 4

3

私の仮定:

  1. MVC プロジェクトとは別の Thread/AppDomain でワークフロー プロジェクトを実行しています。
  2. IUserRepoHttpContext に依存しています

私の仮定が正しければ、Workflow プロジェクトはHttpContext.Current.

WindowsWorkflow プロジェクトは常に実行されます (正しく理解していれば、実際にはこの技術では機能しませんでした)。MVC は HTTP リクエストに基づいています。HttpContext.Currentリクエストがある場合にのみ設定されます。リクエストがない場合、この変数は null です。リクエストがないのに、Workflow インスタンスがアクセスしようとするとどうなりますHttpContextか? 正しい - null 参照例外。または、あなたの場合、依存関係解決の例外です。

するべきこと:

  1. コンテナー登録をモジュール (すべてのドメイン クラスのドメイン モジュール) に分割します。次に、MVC モジュール:User.Currentまたは などのすべての MVC 仕様HttpContext.Current。そして、すべてのワークフロー固有の実装を含むワークフロー モジュール (必要な場合)。
  2. ワークフローの初期化時に、ドメインとワークフロー モジュールを含む autofac コンテナーを作成し、MVC の依存関係を除外します。MVC コンテナーの場合 - ワークフロー モジュールなしで作成します。
  3. IUserRepoHttpContext に依存しない実装を作成する場合。おそらく、これが最も問題になるでしょう。

Azure での Quartz.Net の実行についても同様のことを行いました。これについては、私のブログ記事http://tech.trailmax.info/2013/07/quartz-net-in-azure-with-autofac-smoothness/を参照してください。この投稿は直接の助けにはなりませんが、autofac モジュールを分割する理由を説明します。

コメントごとに更新: WebApi は、ここで多くのことを明確にします。WebApi リクエストは、MVC リクエストと同じパイプラインを通過しません。また、WebApi コントローラーは HttpContext にアクセスできません。この回答を参照してください。

ここで、wepApi コントローラーで行っていることによっては、IUserRepoMVC と WebApi の両方で動作できるように実装を変更する必要がある場合があります。

于 2014-02-16T00:02:23.270 に答える