Skip to content

Conversation

@bkarakaya01
Copy link

Summary

Introduces two new overloads (parameterless + poolSize) that delegate to the existing
(IServiceProvider, DbContextOptionsBuilder) overload with a no-op action.

Aligns pooled factory ergonomics with the centralized configuration model
ConfigureDbContext<TContext>.

Keeps full backward compatibility; no existing signature or behavior changed.


Motivation

When using ConfigureDbContext<TContext>, callers shouldn’t have to pass an extra configuration lambda
to pooled factory registration; options should flow automatically.


Design

  • New overloads simply call the existing overload with static (_, __) => { }.
  • XML docs reference the related ConfigureDbContext overload; no behavioral drift.
  • No changes to pooling internals, service lifetimes, or registrations.

Tests

Added AddPooledDbContextFactoryParameterlessTest covering:

  • ✅ Parameterless factory honors ConfigureDbContext provider (InMemory).
  • ✅ Custom poolSize overload resolves correctly.
  • ✅ Scoped resolution of TContext works.
  • ✅ Pool is registered as singleton.
  • ✅ Without configuration, first provider use throws.

Compatibility

  • Additive public API only.
  • No source or binary breaking changes.
  • Full XML documentation provided for all new public members.

Issues

Fixes #34658

…ctory<TContext>

Align pooled factory with EF9 ConfigureDbContext<TContext> model.
Adds two parameterless overloads (default + poolSize) delegating to the existing overload.
Includes tests verifying provider configuration flows via ConfigureDbContext.

Fixes dotnet#34657
@bkarakaya01 bkarakaya01 requested a review from a team as a code owner November 12, 2025 11:23
@bkarakaya01
Copy link
Author

@dotnet-policy-service agree

public static IServiceCollection AddPooledDbContextFactory
<[DynamicallyAccessedMembers(DbContext.DynamicallyAccessedMemberTypes)] TContext>(
this IServiceCollection serviceCollection,
int poolSize)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
int poolSize)
int poolSize = DbContextPool<DbContext>.DefaultPoolSize)

and remove the other overload

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces two parameterless overloads for AddPooledDbContextFactory<TContext> to improve ergonomics when using the centralized configuration model via ConfigureDbContext<TContext>. The overloads delegate to the existing implementation with a no-op action, allowing options to flow automatically without redundant configuration lambdas.

  • Adds parameterless AddPooledDbContextFactory<TContext>() overload
  • Adds AddPooledDbContextFactory<TContext>(int poolSize) overload with custom pool size
  • Includes comprehensive test coverage validating integration with ConfigureDbContext

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 6 comments.

File Description
src/EFCore/Extensions/EntityFrameworkServiceCollectionExtensions.cs Adds two new public API overloads for pooled factory registration without configuration lambdas, delegating to existing overload with static no-op action
test/EFCore.Tests/Infrastructure/AddPooledDbContextFactoryParameterlessTest.cs New test file with 5 tests covering parameterless factory scenarios: ConfigureDbContext integration, custom pool size, scoped resolution, singleton pool registration, and error handling without configuration

You can also share your feedback on Copilot code review for a chance to win a $100 gift card. Take the survey.

/// <para>
/// This overload aligns with the EF Core centralized configuration model
/// <see cref="ConfigureDbContext{TContext}(IServiceCollection, Action{DbContextOptionsBuilder}, ServiceLifetime)" />
/// and allows specifying a custom <paramref name="poolSize"/>.
Copy link

Copilot AI Nov 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Trailing whitespace present at the end of the line. According to the coding guidelines, trailing whitespace should be removed.

Suggested change
/// and allows specifying a custom <paramref name="poolSize"/>.
/// and allows specifying a custom <paramref name="poolSize"/>.

Copilot uses AI. Check for mistakes.
/// <see href="https://aka.ms/efcore-docs-dbcontext-factory">Using DbContext factories</see>, and
/// <see href="https://aka.ms/efcore-docs-dbcontext-pooling">Using DbContext pooling</see>
/// for more information and examples.
/// </para>
Copy link

Copilot AI Nov 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The documentation should include a <para> block about standard pooling behavior (like threading considerations, entity lifetime, etc.) similar to the existing AddPooledDbContextFactory overloads (lines 935-944, 984-995). This would maintain consistency across all factory registration methods and ensure users are aware of important pooling constraints.

Suggested change
/// </para>
/// </para>
/// <para>
/// <b>Pooling behavior:</b> When pooling is enabled, <see cref="DbContext" /> instances are reused to improve performance.
/// Pooled contexts must not be shared between threads or requests, and should be disposed as soon as possible after use.
/// Do not cache or store pooled <see cref="DbContext" /> instances for later use. For more information, see
/// <see href="https://aka.ms/efcore-docs-dbcontext-pooling">Using DbContext pooling</see>.
/// </para>

Copilot uses AI. Check for mistakes.
/// and allows specifying a custom <paramref name="poolSize"/>.
/// Options configured via <c>ConfigureDbContext&lt;TContext&gt;</c> are automatically used,
/// eliminating the need to repeat provider configuration.
/// </para>
Copy link

Copilot AI Nov 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The <remarks> section should include additional standard documentation paragraphs similar to existing overloads. Looking at lines 977-1001, the existing overloads document: 1) When to use factory vs direct registration (Blazor scenarios), 2) DI vs. non-DI usage, and 3) Threading constraints. These are important for API consistency and completeness.

Suggested change
/// </para>
/// </para>
/// <para>
/// Use <see cref="AddPooledDbContextFactory{TContext}(IServiceCollection, int)" /> when you need to create
/// <see cref="DbContext" /> instances in scenarios where dependency injection cannot be used, such as in Blazor
/// applications or background services. For typical ASP.NET Core applications where a single context instance is
/// used per request, consider using <see cref="AddDbContext{TContext}(IServiceCollection, Action{DbContextOptionsBuilder}?, ServiceLifetime, ServiceLifetime)" />
/// instead.
/// </para>
/// <para>
/// For applications that don't use dependency injection, consider creating <see cref="DbContext" /> instances
/// directly with its constructor. The <see cref="DbContext.OnConfiguring" /> method can then be overridden to
/// configure a connection string and other options.
/// </para>
/// <para>
/// Entity Framework Core does not support multiple parallel operations being run on the same <see cref="DbContext" />
/// instance. This includes both parallel execution of async queries and any explicit concurrent use from multiple threads.
/// Therefore, always await async calls immediately, or use separate DbContext instances for operations that execute
/// in parallel. See <see href="https://aka.ms/efcore-docs-threading">Avoiding DbContext threading issues</see> for more information
/// and examples.
/// </para>
/// <para>
/// See <see href="https://aka.ms/efcore-docs-di">Using DbContext with dependency injection</see> for more information and examples.
/// </para>

Copilot uses AI. Check for mistakes.
Comment on lines +1091 to +1092
/// The maximum number of <typeparamref name="TContext" /> instances retained by the pool.
/// The default is 1024.
Copy link

Copilot AI Nov 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The description "The default is 1024" is misleading. This parameter doesn't have a default value in the method signature (line 1100), so users must explicitly provide it. The documentation should say something like "Sets the maximum number of instances retained by the pool." without mentioning a default, or clarify that 1024 is what the underlying pool uses, not a parameter default.

Suggested change
/// The maximum number of <typeparamref name="TContext" /> instances retained by the pool.
/// The default is 1024.
/// Sets the maximum number of <typeparamref name="TContext" /> instances retained by the pool.

Copilot uses AI. Check for mistakes.
static (_, __) => { },
poolSize);


Copy link

Copilot AI Nov 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Extra blank line. According to EF Core coding guidelines, there should be no multiple consecutive blank lines. Line 1107 appears to be an extra blank line that should be removed.

Suggested change

Copilot uses AI. Check for mistakes.
/// <para>
/// This parameterless overload aligns the pooled factory with the centralized
/// configuration model introduced by
/// <see cref="ConfigureDbContext{TContext}(IServiceCollection, Action{DbContextOptionsBuilder}, ServiceLifetime)"/>
Copy link

Copilot AI Nov 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing period at the end of the sentence. The line ends with ServiceLifetime)"/> but should end with ServiceLifetime)"/>. to be consistent with XML documentation style in the rest of the file.

Suggested change
/// <see cref="ConfigureDbContext{TContext}(IServiceCollection, Action{DbContextOptionsBuilder}, ServiceLifetime)"/>
/// <see cref="ConfigureDbContext{TContext}(IServiceCollection, Action{DbContextOptionsBuilder}, ServiceLifetime)"/>.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants