Open Closed

Scoped Db Context #1265


User avatar
0
alkaabi created
  • ABP Framework version: v4.3.0
  • UI type: Angular
  • DB provider: EF Core
  • Tiered (MVC) or Identity Server Separated (Angular): yes
  • Exception message and stack trace:
  • Steps to reproduce the issue:

I am using a third-party reporting tool in our Abp application which uses a repository as its datsource. The repository's lifetime exceeds the lifetime of the HTTP request that creates the repository. Whenever I use the dafualt Abp repositories, an exception occures saying that services has been already disposed. This is because (I think) I am trying to use dbcontext beyond request liftime. As far as as I know, Abp registers dbcontext as transient lifetime dependency by default using IDbContextProvider provider.

Any idea how to create another db context provider similar to Abp but with a scoped liftime dependency so I can use the repository outisde the http request context ?


7 Answer(s)
  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    Can you share some code?

    You can get repository from other IServiceProvider eg scope service provider of Root

  • User Avatar
    0
    alkaabi created

    I have created another another db context provider which inherits from Abp db context provider :

     public interface IScopedDbContextProvider<TDbContext> : 
            IDbContextProvider<TDbContext> where TDbContext: IEfCoreDbContext
     {
     }
    
        public class ScopedDbContextProvider<TDbContext> : 
            UnitOfWorkDbContextProvider<TDbContext>, IScopedDbContextProvider<TDbContext> where TDbContext : IEfCoreDbContext
      {
            public ScopedDbContextProvider(IUnitOfWorkManager unitOfWorkManager,
                IConnectionStringResolver connectionStringResolver,
                ICancellationTokenProvider cancellationTokenProvider,
                ICurrentTenant currentTenant,
                IOptions<AbpDbContextOptions> options) :base(
                    unitOfWorkManager,
                    connectionStringResolver,
                    cancellationTokenProvider,
                    currentTenant,
                    options)
      {
    
      }
    

    Then I registered the provider as a siglton

    context.Services.TryAddSingleton(typeof(IScopedDbContextProvider<>), typeof(ScopedDbContextProvider<>));
    

    Then I created custom repository and I used that new IScopedDbContextProvider in the repository

     public class RepPersonRepository : EfCoreRepository<JundDbContext, Person, Guid>, IRepPersonRepository
        {
            public RepPersonRepository(IScopedDbContextProvider<JundDbContext> dbContextProvider) : base(dbContextProvider)
            {
    
            }
        }
    

    Then I used the repository inside a regular Abp Application Service

     public class ReportingDataSourceService: ApplicationService, IReportingDataSourceService
        {
            private readonly IRepPersonRepository _personRepository;
            public ReportingDataSourceService()
            {
                // We use this parameterless constructor in the Data Source Wizard only, and not for the actual instantiation of the repository object.
                throw new NotSupportedException();
            }
            public ReportingDataSourceService(IRepPersonRepository perosnRepository)
            {
                _personRepository = perosnRepository;
            }
    
            public  IList<PersonDetailsDto> GetAllPeople()
            {
    
                return ObjectMapper.Map<IList<Person>, IList<PersonDetailsDto>>(
                    _personRepository.WithDetailsAsync(
                        p => p.Rank,
                        p => p.ServiceNumberPrefix,
                        p => p.BirthLocation,
                        p => p.ContactAddresses
                    ).Result.ToList());
    
            }
    }
    

    Whenever I call the endpoint using swagger UI, everything works fine and I get the result but when I set the service as datasource for the report I get this error:

    All Objects have been disposed from repository as shown below

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    but when I set the service as datasource for the report I get this error:

    How does the report activate the ReportingDataSourceService?

  • User Avatar
    0
    alkaabi created

    Hi,

    I am activating through someting called ObjectDataSourceProvider. I dont really know about the implemenation details of that class and how the service get registered. That class comes part of Devexpress Reporting suite. To get an idea od how this is done, I will share their example of how they are doing it with standard ASP .Net Core App and EF Core:

    https://github.com/DevExpress-Examples/Reporting-Entity-Framework-Core-In-AspNet-Core

    I would appreciate if you could guide me how to inetgrate this with Abp using Abp infrastructure.

    Thanks

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi alkaabi

    Can I check it remotely? liming.ma@volosoft.com

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    https://github.com/alkaabi82/Acme.Bookstore/issues/1#issuecomment-837920654

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    Problem has beed resolved.

Made with ❤️ on ABP v8.2.0-preview Updated on March 25, 2024, 15:11