8

Ninject、Entity Framework、およびサービスレイヤーを備えた作業ユニットパターンを使用するMVC3プロジェクトがあります。

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

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...
    }
}
4

2 に答える 2

5

InRequestScope'dオブジェクトはDisposeリクエストの最後にdであるため、この場合は使用できません。InThreadScopeまた、UoWをいくつかのタスクに再利用するため、適合しません。

AsyncServiceただし、NamedScope拡張機能を使用して、内のすべてのオブジェクトのスコープオブジェクトとして自分を宣言することができます。

http://www.planetgeek.ch/2010/12/08/how-to-use-the-additional-ninject-scopes-of-namedscope/を参照してください

于 2012-05-19T23:13:26.463 に答える
0

これは、過去にChildKernelプラグインを使用して使用した厄介なソリューションです(Namedスコープの方がはるかにクリーンだと思います)。基本的に、私は子カーネルを作成し、UoWに関連するすべてのものを子カーネルのシングルトンとしてスコープします。次に、タスクごとに新しい子カーネルを作成し、UoWを処理して、コミットまたはロールバックします。

IAsyncTask1つのメソッドを持つインターフェイスです。Execute()

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;
}
于 2012-05-21T13:40:52.863 に答える