1

Net core repository pattern. I have below piece of code

   public class MapFileUploadBusinessLogic : IMapFileUploadBusinessLogic
     {
      public MapFileUploadBusinessLogic(IServiceScopeFactory scopeFactory, IOptions<AuthenticationConfig> authenticationConfig, IOptions<ADFClient> AdfClient, IUnitOfWork unitOfWork, IConfiguration configuration, IMapper mapper, ILogger<MapFileUploadBusinessLogic> logger)
        {
            UnitOfWork = unitOfWork ?? throw new ArgumentNullException(nameof(unitOfWork));
            Configuration = configuration ?? throw new ArgumentNullException(nameof(configuration));
            CoordinateReferenceSystemRepository = UnitOfWork.GetRepository<CoordinateReferenceSystem>();
            this.Logger = logger ?? throw new ArgumentNullException(nameof(logger));
            MapUploadRepository = UnitOfWork.GetRepository<MapUpload>();
            azureDataFactoryRepository = unitOfWork.GetAzureRepository();
            this._authenticationConfig = authenticationConfig.Value;
            this._ADFClient = AdfClient.Value;
            this.scopeFactory = scopeFactory;
        }
 public AuthenticationConfig _authenticationConfig { get; set; }

 public ADFClient _ADFClient { get; set; }
 public IConfiguration Configuration { get; }
 private IUnitOfWork UnitOfWork { get; }
 private IDbRepository<MapUpload> MapUploadRepository { get; set; }

 public async Task UploadMapFile(List<MapFileUploadEntity> mapFileUploadEntities)
        {
            Dictionary<string, object> parameters = new Dictionary<string, object>
            {
                {"Parameters", mapFileUploadEntities }
            };
            DataFactoryManagementClient dataFactoryManagementClient = azureDataFactoryRepository.InitiateConnection(_authenticationConfig);

            var result = await azureDataFactoryRepository.RunADFPipeline(dataFactoryManagementClient, parameters, _ADFClient, ApplicationConstants.SciHubPipeline);

            await Task.Delay(15000);

            ADFPipeLineStatus aDFPipeLineStatus = await azureDataFactoryRepository.GetPipelineInfoAsync(dataFactoryManagementClient, _ADFClient, result);
            if(aDFPipeLineStatus.Status == "Succeeded")
            {
               var mapUploadData = await this.MapUploadRepository.GetAsync(x => mapFileUploadEntities.Any(m => m.MapName == x.MapName)).ConfigureAwait(false);
               //push notification
            }
            else if(aDFPipeLineStatus.Status == "Failed")
            {
                
                MapUpload mapUpload = await MapUploadRepository.GetFirstOrDefaultAsync(x => x.MapId == 9);
                var mapUploadData = await this.MapUploadRepository.GetAsync(x => mapFileUploadEntities.Any(m => m.MapName == x.MapName)).ConfigureAwait(false);
                //push notification
            }
        }

In the above code when I call await this.MapUploadRepository.GetAsync(x => mapFileUploadEntities.Any(m => m.MapName == x.MapName)).ConfigureAwait(false); it throws

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.\r\nObject name: 'MyContext'."

Is the Task.Delay making this problem? I have below registration in my startup.cs

services.AddDbContext<MyContext>(options =>
           options.UseSqlServer(this.Configuration["AzureSQLConnectionString"]));

services.AddScoped<IUnitOfWork, UnitOfWork>();

Can someone help me to understand what I am doing wrong here? Any help would be appreciated. Thanks

Amit Joshi
  • 15,448
  • 21
  • 77
  • 141
Mr Perfect
  • 585
  • 8
  • 30
  • Please, provide full code of the class. It seems like the issue is not in `UploadMapFile` method – Alexander Aug 08 '20 at 10:05
  • Thanks Alexander. I added but Dbcontext will disposes after the await Task.Delay(15000);? – Mr Perfect Aug 08 '20 at 10:15
  • Hi Alexander I tried something like this using (var serviceScope = scopeFactory.CreateScope()) { var db = serviceScope.ServiceProvider.GetRequiredService(); var blogs = db.MapUpload.Where(x => x.MapName == "test").FirstOrDefault();} It worked for me – Mr Perfect Aug 08 '20 at 10:44
  • But this dint work MapUpload mapUpload = await MapUploadRepository.GetFirstOrDefaultAsync(x => x.MapId == 9); that means my Unitofwork and repository still holding disposed context – Mr Perfect Aug 08 '20 at 10:45

1 Answers1

0

Make sure the caller of your UploadMapFile() method (as well as ALL the higher methods in this call stack) is awaiting the retuned Task. If instead somewhere in the call stack you return void instead of Task, the call will be ended and DbContext will be disposed.

This problem is discussed in detail here: Cannot access a disposed object in ASP.NET Core when injecting DbContext