无法访问ABP中的Hangfire经常性作业上的已处置对象(在DbContext上)错误

时间:2018-09-07 09:47:28

标签: c# .net-core unit-of-work aspnetboilerplate hangfire

我正在尝试在应用程序启动时设置Hangfire经常性作业,但是在该作业中,如果我尝试使用注入的IRepository,则在尝试执行查询时会给出与DbContext相关的错误:

System.ObjectDisposedException
Cannot access a disposed object. A common cause of this error is disposing a context that was resolved from dependency injection and then later trying to use the same context instance elsewhere in your application. This may occur if you are calling Dispose() on the context, or wrapping the context in a using statement. If you are using dependency injection, you should let the dependency injection container take care of disposing context instances. Object name: 'WsApplicationDbContext'.

System.ObjectDisposedException: Cannot access a disposed object. A common cause of this error is disposing a context that was resolved from dependency injection and then later trying to use the same context instance elsewhere in your application. This may occur if you are calling Dispose() on the context, or wrapping the context in a using statement. If you are using dependency injection, you should let the dependency injection container take care of disposing context instances.
Object name: 'WsApplicationDbContext'.
   at Microsoft.EntityFrameworkCore.DbContext.CheckDisposed()
   at Microsoft.EntityFrameworkCore.Internal.InternalDbSet`1.get_EntityType()
   at Microsoft.EntityFrameworkCore.Internal.InternalDbSet`1.get_EntityQueryable()
   at Microsoft.EntityFrameworkCore.Internal.InternalDbSet`1.System.Linq.IQueryable.get_Provider()
   at System.Linq.Queryable.Select[TSource,TResult](IQueryable`1 source, Expression`1 selector)
   at WsApplication.RecurringJobs.Jobs.ContainerIsBookedOffHireRecurringJob.TestJob() in C:\Projects\boxman\aspnet-core\src\WsApplication.Application\RecurringJobs\Jobs\ContainerIsBookedOffHireRecurringJob.cs:line 26

我已经完全按照ABP documentation中的说明注册了Hangfire。 另外,我正在<ApplicationName>.Web.Core模块中这样注册我的工作:

public override void PostInitialize()
{
    ...

    // set up recurring background jobs
    var job = IocManager.Resolve<ContainerIsBookedOffHireRecurringJob>();
    RecurringJob.AddOrUpdate<ContainerIsBookedOffHireRecurringJob>("TestJobWithRepository", j => j.TestJob(), Cron.Daily);
}

我的工作方法只是尝试使用注入的存储库进行查询。

public class ContainerIsBookedOffHireRecurringJob : BaseRecurringJob
{
    private readonly IRepository<ContractLineMovement, int> _contractLineMovementRepository;

    public ContainerIsBookedOffHireRecurringJob(
        IIocResolver iocResolver,
        IRepository<ContractLineMovement, int> contractLineMovementRepository
    ) : base(iocResolver)
    {
        _contractLineMovementRepository = contractLineMovementRepository;
    }

    public void TestJob()
    {
        var testQuery = from contractLineMovement in _contractLineMovementRepository.GetAll()
                        select contractLineMovement;

        testQuery.ToList().ForEach(t =>
        {
            Logger.Debug("Fetched ContractLineMovement ID: " + t.Id + " Type: " + t.ContractWorkFlowEventId);
        });
    }
}

我已经设法通过直接在WsApplicationDbContext中解析一个BaseRecurringJob来解决此问题,但是我真的不喜欢这种解决方案。我不明白为什么它不能简单地与依赖注入一起使用。 是因为我要在启动时注册它们吗?我需要某种自定义的Job Activator吗?

任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:3)

添加[UnitOfWork]属性并将其设置为virtual方法:

[UnitOfWork]
public virtual void TestJob()
{
    ...
}

请参阅:UnitOfWork Attribute Restrictions

  

您可以将UnitOfWork属性用于:

     
      
  • 用于在接口上使用的类的所有 public public虚拟方法(就像在服务接口上使用的应用程序服务一样)。
  •   
  • 用于自注入类的所有公共虚拟方法(例如 MVC控制器 Web API控制器)。
  •   
  • 所有受保护的虚拟方法。
  •