8

我有一个 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...
    }
}
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 插件使用的一个混乱的解决方案(我认为命名范围会更干净)。基本上我创建了一个子内核,并将与 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-05-21T13:40:52.863 回答