Search code examples
c#entity-frameworkasp.net-coreentity-framework-core.net-5

NET 5 and EF: how to use AddPooledDbContextFactory in liu of DbContext in services


I recently came across AddPooledDbContextFactory concept as part of my NET 5 self-education piece and am keen to implement it properly. However, I am not sure how to use it with generics that I generally use.

Example of my current setup:

public void ConfigureServices(IServiceCollection services)
   {
        services.AddDbContext<TestDbContext>(
                (s, o) => o.UseNpgsql(Configuration.GetConnectionString("DatabaseConnection"))
                           .UseLoggerFactory(s.GetRequiredService<ILoggerFactory>()));

// other code //
    }

my repository generic:

    public class Repository<T> : IRepository<T> where T
    {
        private readonly TestDbContext _dbContext;
        public Repository(TestDbContext dbContext)
        {
            _dbContext = dbContext;
        }
        

        public async Task Create(T entity)
        {
           await _dbContext.Set<T>().AddAsync(entity);
           await _dbContext.SaveChangesAsync();
        }

        // other methods //
   }

this is invoked in following manner as example:

public class WeatherForecastController : ControllerBase
{
    
    private readonly IRepository<Test> testRepo;

    public WeatherForecastController(IRepository<Test> testRepo)
    {
        this.testRepo= testRepo;
    }

    [HttpGet]
    public async Task<IEnumerable<WeatherForecast>> GetAsync()
    {
        await testRepo.Create(new Test { Name = "Superman" });
        
        // other code
    }

}

I would like to convert this to use the new AddPooledDbContextFactory concept but cannot find enough documentation to figure out how to do this.

Atm only thing that comes to mind is using statements at each method but that doesn't make sense.

Any advice on this?


Solution

  • Documentation is not yet complete and is in progress, you track this issue https://github.com/dotnet/EntityFramework.Docs/issues/2523

    You can also a look at the tests for AddPooledDbContextFactory to see how to register DbContext with https://github.com/dotnet/efcore/search?q=AddPooledDbContextFactory

    for example to register DbContext:

    services.AddPooledDbContextFactory<TContext>(ob =>
        ob.UseSqlServer("ConnectionString").EnableServiceProviderCaching(false), poolSize: 32)
    

    Then in your class, inject an IDbContextFactory<TContext> and use it like this:

    using(var context = _factory.CreateDbContext())
    {
        var orders = await context.Orders.Where(o => o.Id > 3).ToListAsync();
    }
    

    According to this post:

    Note that the DbContext instances created in this way are not managed by the application's service provider and therefore must be disposed by the application

    You can also check out this post to see how to use IDbContextFactory: https://learn.microsoft.com/en-us/aspnet/core/blazor/blazor-server-ef-core?view=aspnetcore-5.0