Mohammad Shadmehr
Mohammad Shadmehr

Reputation: 695

System.ObjectDisposedException in ABP

I have the following class in the Core Layer:

RequestManager:

public class RequestManager: MyCarParkServiceBase, ISingletonDependency
{
    public static List<HitchRequest> GlobalHitchRequestList = new List<HitchRequest>();
    public static List<CarparkRequest> GlobalCarparkRequestList = new List<CarparkRequest>();
    public static Dictionary<CarparkRequest, List<HitchRequest>> GlobalRequestList = new Dictionary<CarparkRequest, List<HitchRequest>>();

    private readonly IRepository<HitchRequest, long> _hitchRequestRepository;
    private readonly IRepository<CarparkRequest, long> _carparkRequestRepository;

    public RequestManager(IRepository<HitchRequest, long> hitchRequestRepository,
                          IRepository<CarparkRequest, long> carparkRequestRepository)
    {
        _hitchRequestRepository = hitchRequestRepository;
        _carparkRequestRepository = carparkRequestRepository;
    }

    public void LoadAllActiveRequests()
    {
        //System.ObjectDisposedException Exception!!!! 
        _hitchRequestRepository.GetAll().Include(p => p.CarPark).Where(p => p.IsActive).ToList().ForEach(p => GlobalHitchRequestList.Add(p));

        _carparkRequestRepository.GetAllList(p => p.IsActive).ForEach(p => GlobalCarparkRequestList.Add(p));

        ManageRequestList();
    }
}

I am getting the following error when trying to use the GetAll() method:

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.'

If I use GetAllList() instead and remove the Include() from it, then it works fine. I call the LoadAllActiveRequests() in the PostInitialize() of the CoreModule class:

public override void PostInitialize()
{
   IocManager.RegisterIfNot<IChatCommunicator, NullChatCommunicator>();

   IocManager.Resolve<ChatUserStateWatcher>().Initialize();
   IocManager.Resolve<RequestManager>().LoadAllActiveRequests();
   IocManager.Resolve<AppTimes>().StartupTime = Clock.Now;
}

Upvotes: 2

Views: 1550

Answers (2)

aaron
aaron

Reputation: 43098

Add [UnitOfWork] attribute and make it a virtual method:

[UnitOfWork]
public virtual void LoadAllActiveRequests()
{
    // ...
}

See: UnitOfWork Attribute Restrictions

You can use the UnitOfWork attribute for:

  • All public virtual methods for self injected classes (Like MVC Controllers and Web API Controllers).

Upvotes: 4

Mohammad Shadmehr
Mohammad Shadmehr

Reputation: 695

I injected the UnitOfWorkManager and changed the method to the following and it worked!

    public void LoadAllActiveRequests()
    {
        using (var unitOfWork = _unitOfWorkManager.Begin())
        {
            _hitchRequestRepository.GetAll().Include(p => p.CarPark).Where(p => p.IsActive).ToList().ForEach(p => GlobalHitchRequestList.Add(p));

            _carparkRequestRepository.GetAllList(p => p.IsActive).ForEach(p => GlobalCarparkRequestList.Add(p));

            ManageRequestList();
        }
    }

Still not quite sure why the [UnitOfWork] attribute was not working for my case!

Upvotes: 0

Related Questions