0

I have been working on my own project that I have been using .Net Core 3.1 and Linq2b ORM tool for. I have a problem that is about inserting data by using async metot. I want to insert a log data. There is a method that is called InsertWithInt32IdentityAsync in Linq2Db. This method returns an error that is called Cannot access a disposed object.Object name: IServiceProvider.

Here is the implementations.

    [HttpPost("createpost")]
    [Authorize]
    public virtual async Task<JsonResult> CreatePost([FromForm] PostCreateApi model)
    {
        var serviceResponse = _postService.Create(model);

        if (serviceResponse.Warnings.Count > 0 || serviceResponse.Warnings.Any())
            return BadResponse(new ResultModel
            {
                Status = false,
                Message = serviceResponse.Warnings.First()
            });
        
        //Here returns an error
        await _logService.InsertLogAsync(Domain.Enumerations.LogLevel.Information, $"PostsController- Create Post Request", JsonConvert.SerializeObject(model));

        return OkResponse(new PostListDto
        {
            Id = serviceResponse.Data.Id,
            Text = serviceResponse.Data?.Text,
            ImageUrl = serviceResponse.Data.ImageUrl?.ToString(),
            CreatedByUserName = serviceResponse.Data?.CreatedByUserName,
            CreatedByUserPhoto = serviceResponse.Data?.CreatedByUserPhoto,
            CreatedDate = serviceResponse.Data.CreatedDate,
            VideoUrl = serviceResponse.Data?.VideoUrl,
            PostType = serviceResponse.Data?.PostType,
            Comments = null
        });
    }

Here is InsertLogAsync method.

 public virtual async Task<Log> InsertLogAsync(LogLevel logLevel, string shortMessage, string fullMessage = "", AppUser appUser = null)
    {
        var log = new Log
        {
            LogLevel = logLevel,
            ShortMessage = shortMessage,
            FullMessage = fullMessage,
            IpAddress = _webHelper.GetCurrentIpAddress(),
            CustomerId = appUser?.Id,
            PageUrl = _webHelper.GetThisPageUrl(true),
            ReferrerUrl = _webHelper.GetUrlReferrer(),
            CreatedDate = DateTime.UtcNow
        };

        await _logRepository.InsertAsync(log);

        return log;
    }

Here is BaseDataProvider InsertEntityAsync method.

  public virtual async Task<TEntity> InsertEntityAsync<TEntity>(TEntity entity) where TEntity : 
  BaseEntity
    {
        using var dataContext = CreateDataConnection();
        entity.Id = await dataContext.InsertWithInt32IdentityAsync(entity);
        return entity;
    }

Here is StackTrace.

at Microsoft.Extensions.DependencyInjection.ServiceLookup.ThrowHelper.ThrowObjectDisposedException() at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope.GetService(Type serviceType) at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetService[T](IServiceProvider provider) at FluentMigrator.Infrastructure.MigrationContext..ctor(IQuerySchema querySchema, IServiceProvider serviceProvider, Object context, String connection) at DevPlatform.Data.Migrations.MigrationManager.CreateNullMigrationContext() in C:\Projects\DevPlatform\DevPlatform.Data\Migrations\MigrationManager.cs:line 165 at DevPlatform.Data.Migrations.MigrationManager.GetCreateTableExpression(Type type) in C:\Projects\DevPlatform\DevPlatform.Data\Migrations\MigrationManager.cs:line 240 at DevPlatform.Data.Mapping.FluentMigratorMetadataReader.<>c__DisplayClass2_01.<GetAttribute>b__1(Type entityType) in C:\Projects\DevPlatform\DevPlatform.Data\Mapping\FluentMigratorMetadataReader.cs:line 42 at System.Collections.Concurrent.ConcurrentDictionary2.GetOrAdd(TKey key, Func2 valueFactory) at DevPlatform.Data.Mapping.FluentMigratorMetadataReader.<>c__DisplayClass2_01.b__0(ValueTuple2 t) in C:\Projects\DevPlatform\DevPlatform.Data\Mapping\FluentMigratorMetadataReader.cs:line 42 at System.Collections.Concurrent.ConcurrentDictionary2.GetOrAdd(TKey key, Func2 valueFactory) at DevPlatform.Data.Mapping.FluentMigratorMetadataReader.GetAttribute[T](Type type, MemberInfo memberInfo) in C:\Projects\DevPlatform\DevPlatform.Data\Mapping\FluentMigratorMetadataReader.cs:line 40 at DevPlatform.Data.Mapping.FluentMigratorMetadataReader.GetAttributes[T](Type type, Type attributeType, MemberInfo memberInfo) in C:\Projects\DevPlatform\DevPlatform.Data\Mapping\FluentMigratorMetadataReader.cs:line 76 at DevPlatform.Data.Mapping.FluentMigratorMetadataReader.GetAttributes[T](Type type, Boolean inherit) in C:\Projects\DevPlatform\DevPlatform.Data\Mapping\FluentMigratorMetadataReader.cs:line 97 at LinqToDB.Mapping.MappingSchema.<>c__DisplayClass51_01.b__0(IMetadataReader mr) at System.Linq.Enumerable.d__1813.MoveNext() at System.Collections.Generic.LargeArrayBuilder1.AddRange(IEnumerable1 items) at System.Collections.Generic.EnumerableHelpers.ToArray[T](IEnumerable1 source) at LinqToDB.Mapping.MappingSchema.GetAttributes[T](Type type, Boolean inherit) at LinqToDB.Mapping.MappingSchema.GetAttributes[T](Type type, Func2 configGetter, Boolean inherit, Boolean exactForConfiguration) at LinqToDB.Mapping.MappingSchema.GetAttribute[T](Type type, Func2 configGetter, Boolean inherit) at LinqToDB.Mapping.EntityDescriptor.Init() at LinqToDB.Mapping.EntityDescriptor..ctor(MappingSchema mappingSchema, Type type) at LinqToDB.Mapping.MappingSchema.<>c.b__92_0(ICacheEntry o, <>f__AnonymousType1312 key, MappingSchema context) at LinqToDB.Common.Internal.Cache.CacheExtensions.GetOrCreate[TItem,TKey,TContext](IMemoryCache cache, TKey key, TContext context, Func4 factory) at LinqToDB.Mapping.MappingSchema.GetEntityDescriptor(Type type) at LinqToDB.Linq.QueryRunner.GetType[T](T obj, IDataContext db) at LinqToDB.Linq.QueryRunner.InsertWithIdentity`1.d__2.MoveNext()

enter image description here

enter image description here

enter image description here

enter image description here

Ismail Dogan
  • 295
  • 2
  • 20
  • 1
    There are at least two situations when it fails. You have disposed DataConnection in IOC container and trying to run query. Or you have missed `await` in other place. Also provide full stack trace, – Svyatoslav Danyliv Mar 29 '21 at 04:46
  • Can you post the stack trace for the exception? – Paulo Morgado Mar 29 '21 at 10:18
  • @SvyatoslavDanyliv I have just added stack trace. – Ismail Dogan Mar 29 '21 at 15:32
  • @PauloMorgado I have just added stack trace. You can see above. – Ismail Dogan Mar 29 '21 at 15:33
  • 1
    Your MigrationManager is capturing a MigrationContext as a field and trying to use its ServiceProvider when creating a "null" MigrationContext. That ServiceProvider looks like it was already disposed by that point. You could look into the lifecycles in your dependency injection configuration, but you should probably reconsider how you're constructing that MigrationContext in the first place. – StriplingWarrior Mar 29 '21 at 16:00

1 Answers1

0

The problem has been solved by editing CreateTableExpressionBuilder and calling _migrationContext instead of calling CreateNullMigrationContext function.

Instead of the following code block;

    public virtual CreateTableExpression GetCreateTableExpression(Type type)
    {
        var expression = new CreateTableExpression { TableName = NameCompatibilityManager.GetTableName(type) };
        var builder = new CreateTableExpressionBuilder(expression, CreateNullMigrationContext());

        RetrieveTableExpressions(type, builder);

        return builder.Expression;
    }

I have changed CreateTableExpressionBuilder for this problem.

 public virtual CreateTableExpression GetCreateTableExpression(Type type)
    {
        var expression = new CreateTableExpression { TableName = NameCompatibilityManager.GetTableName(type) };
        var builder = new CreateTableExpressionBuilder(expression, _migrationContext);

        RetrieveTableExpressions(type, builder);

        return builder.Expression;
    }

CreateNullMigrationContext function returns an error as I have mentioned about it.

 protected IMigrationContext CreateNullMigrationContext()
    {
        return new MigrationContext(new NullIfDatabaseProcessor(), 
          _migrationContext.ServiceProvider, null, null);
    }

Thank you very much. @StriplingWarrior, @Paulo Morgado and @Svyatoslav Danyliv

Ismail Dogan
  • 295
  • 2
  • 20