3

メイン フロント エンドとして MVC3 を使用する 4 層システムを構築していますが、サービス層によって非同期に実行され、MVV が Ajax を使用して表示する進行状況を報告する長時間実行タスクが含まれています。私が依存性注入 (DI) に Autofac を使用しているのは、主にインターフェイスとドキュメントが優れており、高速であるためです ( Philip Mateescu によるDI 速度に関するこの優れた研究を参照してください)。

私の質問は、注入されたアイテムの 2 つのスコープを処理するように Autofac を設定する方法についてです。つまり、MVC3 の依存関係は PerHttpRequest である必要がありますが、非同期タスクの依存関係は InstancePerLifetimeScope である必要があります。

明らかに、サービス層は、長時間実行されるタスクの依存関係を解決するために別の DI を使用する必要があります。それを行う最善の方法は何ですか?

4

1 に答える 1

7

更新-2014年6月

AutoFacの使用に関するベストプラクティスが進み、MVCが変更されたため、この回答を更新しました。変更点は、AutoFacのベストプラクティスは、.InstancePerLifetimeScope()サフィックスを使用して、アクセスの存続期間全体にわたって持続する必要のあるインスタンスを定義することです(MVCの場合はHttpRequest)。例については、以下を参照してください。

builder.RegisterType<MyDbContext>().As<IMyDbContext>().InstancePerLifetimeScope();

これにより、タスク内で作成する新しいライフタイムスコープの名前を指定する必要がなくなります(以下の更新された元の回答を参照してください)。

MVCでのタスクに関するその他の注意事項として、役立つと思われるものがいくつかあります。

  • 新しいasync/awaitを使用している場合は、新しいライフタイムスコープは必要ありません。Aysnc / awaitは現在のコンテキストを維持し、単にスレッドを解放して、負荷がかかった状態でWebのパフォーマンスを向上させます。
  • 本当にバックグラウンドで何かを実行したい場合は、警告が表示されます-いくつかの問題があります。非同期の専門家であるStephenClearyによるこの役立つブログ投稿を読むことをお勧めします。
  • 本当に便利な組み合わせの1つは、SignalRをMVCと組み合わせて使用​​して、進行状況を報告し、ユーザーがキャンセルできるようにすることです。これは私にとってうまくいきました。

元の投稿ですが、更新されています(注:上記のようにライフタイムスコープインスタンスを登録する必要があります)

GoogleAutofacグループを介して依存関係のある非同期タスクを処理する方法を見つけました。MVCレベルのコンテナーにアクセスして、解決の新しい有効期間スコープを作成できることがわかりました。それを行うにはいくつかの方法がありますが、Alex Meyer-Gleaves(専門家)によるこの回答が答えを提供します。Alexは、スコープが異なるタスクを実行するために、以下のコードを提案しています。

public void Run<T>(Action<T> action)
{
  Task.Factory.StartNew(delegate
  {
    using (var container = AutofacDependencyResolver.Current
                           .ApplicationContainer.BeginLifetimeScope())
    {
        var service = container.Resolve<T>();
        action(service);
    }
  });
}

Alexの投稿の主題に関するより詳細なブログ投稿へのリンクがあります。これも非常に便利です。

于 2012-06-12T09:12:09.217 に答える