【问题标题】:Ninject Scope issue with Tasks/Threads任务/线程的 Ninject Scope 问题
【发布时间】:2012-05-18 21:57:17
【问题描述】:

我有一个 MVC3 项目,它使用 Ninject、实体框架和带有服务层的工作单元模式。

我的 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...
    }
}

【问题讨论】:

    标签: asp.net-mvc-3 entity-framework-4 ninject task-parallel-library unit-of-work


    【解决方案1】:

    InRequestScope'd 对象在请求结束时是 Disposed,因此在这种情况下不能使用它。 InThreadScope 也不适合,因为这会在多个任务中重用 UoW。

    您可以做的是将您的 AsyncService 声明为使用 NamedScope 扩展的所有对象的范围对象。

    http://www.planetgeek.ch/2010/12/08/how-to-use-the-additional-ninject-scopes-of-namedscope/

    【讨论】:

    • 有示例代码吗?杰森,你在哪里可以让它工作?我遇到了同样的问题,点击链接没有帮助。
    • 我也有同样的问题,我很想看看这个场景的一些示例代码。
    【解决方案2】:

    这是我过去使用 ChildKernel 插件使用的一个混乱的解决方案(我认为命名范围会更干净)。基本上,我创建了一个子内核,并将与 UoW 相关的所有内容都作为子内核中的单例。然后我为每个任务创建一个新的子内核,处理 UoW,并提交或回滚。

    IAsyncTask是一个接口,有1个方法,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-12-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-27
      相关资源
      最近更新 更多