diff --git a/src/EFCore/Extensions/EntityFrameworkServiceCollectionExtensions.cs b/src/EFCore/Extensions/EntityFrameworkServiceCollectionExtensions.cs index 691e7ba0949..bc3ea06636f 100644 --- a/src/EFCore/Extensions/EntityFrameworkServiceCollectionExtensions.cs +++ b/src/EFCore/Extensions/EntityFrameworkServiceCollectionExtensions.cs @@ -307,7 +307,7 @@ public static IServiceCollection AddDbContextPool(serviceCollection, optionsAction, poolSize); serviceCollection.TryAddSingleton, DbContextPool>(); - serviceCollection.AddScoped, ScopedDbContextLease>(); + serviceCollection.AddScoped, PoolingScopedDbContextLease>(); serviceCollection.AddScoped( sp => sp.GetRequiredService>().Context); @@ -369,6 +369,13 @@ public static IServiceCollection AddDbContext( where TContext : DbContext => AddDbContext(serviceCollection, contextLifetime, optionsLifetime); + // public static IServiceCollection AddDbContext( + // this IServiceCollection serviceCollection, + // ServiceLifetime contextLifetime, + // ServiceLifetime optionsLifetime = ServiceLifetime.Scoped) + // where TContext : DbContext + // => AddDbContext(serviceCollection, contextLifetime, optionsLifetime); + /// /// /// Registers the given context as a service in the . @@ -780,6 +787,9 @@ public static IServiceCollection AddDbContextFactory( typeof(TFactory), lifetime)); + serviceCollection.AddScoped, ScopedDbContextLease>(); + serviceCollection.AddScoped(sp => sp.GetRequiredService>().Context); + return serviceCollection; } diff --git a/src/EFCore/Internal/PoolingScopedDbContextLease.cs b/src/EFCore/Internal/PoolingScopedDbContextLease.cs new file mode 100644 index 00000000000..b556c26b9e6 --- /dev/null +++ b/src/EFCore/Internal/PoolingScopedDbContextLease.cs @@ -0,0 +1,56 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Threading.Tasks; + +namespace Microsoft.EntityFrameworkCore.Internal +{ + /// + /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to + /// the same compatibility standards as public APIs. It may be changed or removed without notice in + /// any release. You should only use it directly in your code with extreme caution and knowing that + /// doing so can result in application failures when updating to a new Entity Framework Core release. + /// + public sealed class PoolingScopedDbContextLease : IScopedDbContextLease, IDisposable, IAsyncDisposable + where TContext : DbContext + { + private DbContextLease _lease; + + /// + /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to + /// the same compatibility standards as public APIs. It may be changed or removed without notice in + /// any release. You should only use it directly in your code with extreme caution and knowing that + /// doing so can result in application failures when updating to a new Entity Framework Core release. + /// + public PoolingScopedDbContextLease(IDbContextPool contextPool) + => _lease = new DbContextLease(contextPool, standalone: false); + + /// + /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to + /// the same compatibility standards as public APIs. It may be changed or removed without notice in + /// any release. You should only use it directly in your code with extreme caution and knowing that + /// doing so can result in application failures when updating to a new Entity Framework Core release. + /// + public TContext Context + => (TContext)_lease.Context; + + /// + /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to + /// the same compatibility standards as public APIs. It may be changed or removed without notice in + /// any release. You should only use it directly in your code with extreme caution and knowing that + /// doing so can result in application failures when updating to a new Entity Framework Core release. + /// + void IDisposable.Dispose() + => _lease.Release(); + + /// + /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to + /// the same compatibility standards as public APIs. It may be changed or removed without notice in + /// any release. You should only use it directly in your code with extreme caution and knowing that + /// doing so can result in application failures when updating to a new Entity Framework Core release. + /// + ValueTask IAsyncDisposable.DisposeAsync() + => _lease.ReleaseAsync(); + } +} diff --git a/src/EFCore/Internal/ScopedDbContextLease.cs b/src/EFCore/Internal/ScopedDbContextLease.cs index 72fd3dce07d..9d6eabae2a3 100644 --- a/src/EFCore/Internal/ScopedDbContextLease.cs +++ b/src/EFCore/Internal/ScopedDbContextLease.cs @@ -15,7 +15,8 @@ namespace Microsoft.EntityFrameworkCore.Internal public sealed class ScopedDbContextLease : IScopedDbContextLease, IDisposable, IAsyncDisposable where TContext : DbContext { - private DbContextLease _lease; + private readonly IDbContextFactory _factory; + private TContext? _context; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -23,8 +24,8 @@ public sealed class ScopedDbContextLease : IScopedDbContextLease - public ScopedDbContextLease(IDbContextPool contextPool) - => _lease = new DbContextLease(contextPool, standalone: false); + public ScopedDbContextLease(IDbContextFactory factory) + => _factory = factory; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -33,7 +34,7 @@ public ScopedDbContextLease(IDbContextPool contextPool) /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public TContext Context - => (TContext)_lease.Context; + => _context = _factory.CreateDbContext(); /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -42,7 +43,7 @@ public TContext Context /// doing so can result in application failures when updating to a new Entity Framework Core release. /// void IDisposable.Dispose() - => _lease.Release(); + => _context!.Dispose(); /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -51,6 +52,6 @@ void IDisposable.Dispose() /// doing so can result in application failures when updating to a new Entity Framework Core release. /// ValueTask IAsyncDisposable.DisposeAsync() - => _lease.ReleaseAsync(); + => _context!.DisposeAsync(); } }