8

私は、Ninject、Entity Framework、および作業単位のパターンをサービスレイヤーで使用するMVC3プロジェクトを持っています。タスク/スレッドに関するNinjectスコープの問題

My AsyncServiceクラスには、ユーザーリポジトリにユーザーを追加するバックグラウンドタスクを開始する関数があります。 私の現在の問題は、DbContextが破棄されたというエラーが出る前に、タスクが数秒間だけ正しく実行されることです。 InRequestScope()がHttpContextと結びついているため、NinjectのInRequestScope()が注入されたデータベースのコンテキストが破棄されているようです。

私はInThreadScope()について読んだことがありますが、MVCプロジェクトで正しく実装する方法がわかりません。

私の質問:私の仕事でNinjectを使う正しい方法は何ですか?

public class AsyncService 
{ 
    private CancellationTokenSource cancellationTokenSource; 
    private IUnitOfWork _uow; 
    public AsyncService(IUnitOfWork uow) 
    { 
     _uow = uow; 
    } 
    public void AsyncStartActivity(Activity activity) 
    { 
    ...snip... 
     this.cancellationTokenSource = new CancellationTokenSource(); 
     var cancellationToken = this.cancellationTokenSource.Token; 
     var task = Task.Factory.StartNew(() => 
      { 
       foreach (var user in activity.UserList) 
       { 
        this._uow.UserRepository.Add(new User() {UserID = user}); 
       } 
       this._uow.Save(); 
      }, cancellationToken); 
    ...snip... 
    } 
} 

答えて

5

InRequestScopeそれはこの場合に使用することができないので、「Dオブジェクトは、要求の終了時にDispose Dです。 InThreadScopeは、UoWをいくつかのタスクに再利用するようには適合しません。

あなたができることは、NamedScope拡張を使用するすべてのオブジェクトのスコープオブジェクトとしてAsyncServiceを宣言していることです。

は、これは私がChildKernelプラグインを使用して、過去に使用した厄介なソリューションですhttp://www.planetgeek.ch/2010/12/08/how-to-use-the-additional-ninject-scopes-of-namedscope/

+3

サンプルコードがあり、1つの方法とのインタフェースでありますか?ジェイソン、あなたはそれを働かせることができますか?私は同じ問題を抱えており、リンクをたどっても助けにはならなかった。 –

+0

私はこの同じ問題がある、私はこのシナリオのいくつかのサンプルコードを見たいと思います。 –

0

を参照してください(私は名前付き範囲が非常にクリーンだと思います)。基本的に私は子カーネルを作成し、子カーネル内のUoWに関するすべてのものをシングルトンとしてスコープします。次に、各タスク用に新しい子カーネルを作成し、UoWを処理し、コミットまたはロールバックします。

IAsyncTaskExecute()

private Task void ExecuteTask<T>() where T:IAsyncTask 
{ 

     var task = Task.Factory.StartNew(() => 
              { 
      var taskKernel = _kernel.Get<ChildKernel>(); 
      var uow = taskKernel.Get<IUnitOfWork>(); 
      var asyncTask = taskKernel.Get<T>(); 

      try 
      { 
       uow.Begin(); 
       asyncTask.Execute(); 
       uow.Commit(); 
      } 
      catch (Exception ex) 
      { 
       uow.Rollback(); 
       //log it, whatever else you want to do 
      } 
      finally 
      { 
       uow.Dispose(); 
       taskKernel.Dispose(); 
      } 
     }); 
     return task; 
}