diff --git a/src/EFCore/Diagnostics/CoreEventId.cs b/src/EFCore/Diagnostics/CoreEventId.cs index f99ba5f3eb3..3dd9e660f6e 100644 --- a/src/EFCore/Diagnostics/CoreEventId.cs +++ b/src/EFCore/Diagnostics/CoreEventId.cs @@ -79,6 +79,7 @@ private enum Id ContextDisposed, DetachedLazyLoadingWarning, ServiceProviderDebugInfo, + RedundantAddServicesCallWarning, // Model events ShadowPropertyCreated = CoreBaseId + 600, @@ -382,6 +383,19 @@ public static readonly EventId PossibleUnintendedReferenceComparisonWarning /// public static readonly EventId DetachedLazyLoadingWarning = MakeInfraId(Id.DetachedLazyLoadingWarning); + /// + /// + /// 'AddEntityFramework*' was called on the service provider, but 'UseInternalServiceProvider' wasn't. + /// + /// + /// This event is in the category. + /// + /// + /// This event uses the payload when used with a . + /// + /// + public static readonly EventId RedundantAddServicesCallWarning = MakeInfraId(Id.RedundantAddServicesCallWarning); + private static readonly string _modelPrefix = DbLoggerCategory.Model.Name + "."; private static EventId MakeModelId(Id id) => new EventId((int)id, _modelPrefix + id); diff --git a/src/EFCore/Diagnostics/CoreLoggerExtensions.cs b/src/EFCore/Diagnostics/CoreLoggerExtensions.cs index 2a678c82669..a8166b222bb 100644 --- a/src/EFCore/Diagnostics/CoreLoggerExtensions.cs +++ b/src/EFCore/Diagnostics/CoreLoggerExtensions.cs @@ -944,6 +944,34 @@ private static string DetachedLazyLoadingWarning(EventDefinitionBase definition, return d.GenerateMessage(p.NavigationPropertyName, p.Entity.GetType().ShortDisplayName()); } + /// + /// Logs for the event. + /// + /// The diagnostics logger to use. + /// The service provider used. + public static void RedundantAddServicesCallWarning( + [NotNull] this IDiagnosticsLogger diagnostics, + [NotNull] IServiceProvider serviceProvider) + { + var definition = CoreResources.LogRedundantAddServicesCall(diagnostics); + + var warningBehavior = definition.GetLogBehavior(diagnostics); + if (warningBehavior != WarningBehavior.Ignore) + { + definition.Log(diagnostics, warningBehavior); + } + + if (diagnostics.DiagnosticSource.IsEnabled(definition.EventId.Name)) + { + diagnostics.DiagnosticSource.Write( + definition.EventId.Name, + new ServiceProviderEventData( + definition, + (d, p) => ((EventDefinition)d).GenerateMessage(), + serviceProvider)); + } + } + /// /// Logs for the event. /// diff --git a/src/EFCore/Diagnostics/LoggingDefinitions.cs b/src/EFCore/Diagnostics/LoggingDefinitions.cs index f0a22c0d983..76d6147286c 100644 --- a/src/EFCore/Diagnostics/LoggingDefinitions.cs +++ b/src/EFCore/Diagnostics/LoggingDefinitions.cs @@ -439,6 +439,15 @@ public abstract class LoggingDefinitions [EntityFrameworkInternal] public EventDefinitionBase LogDetachedLazyLoading; + /// + /// 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. + /// + [EntityFrameworkInternal] + public EventDefinitionBase LogRedundantAddServicesCall; + /// /// 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 diff --git a/src/EFCore/Extensions/EntityFrameworkServiceCollectionExtensions.cs b/src/EFCore/Extensions/EntityFrameworkServiceCollectionExtensions.cs index 80f01cebb7d..050cec2ffa1 100644 --- a/src/EFCore/Extensions/EntityFrameworkServiceCollectionExtensions.cs +++ b/src/EFCore/Extensions/EntityFrameworkServiceCollectionExtensions.cs @@ -508,7 +508,7 @@ private static void AddCoreServices( serviceCollection.TryAdd( new ServiceDescriptor( typeof(DbContextOptions), - p => DbContextOptionsFactory(p, optionsAction), + p => CreateDbContextOptions(p, optionsAction), optionsLifetime)); serviceCollection.Add( @@ -518,7 +518,7 @@ private static void AddCoreServices( optionsLifetime)); } - private static DbContextOptions DbContextOptionsFactory( + private static DbContextOptions CreateDbContextOptions( [NotNull] IServiceProvider applicationServiceProvider, [CanBeNull] Action optionsAction) where TContext : DbContext diff --git a/src/EFCore/Internal/ServiceProviderCache.cs b/src/EFCore/Internal/ServiceProviderCache.cs index c4188c920ad..50b97910110 100644 --- a/src/EFCore/Internal/ServiceProviderCache.cs +++ b/src/EFCore/Internal/ServiceProviderCache.cs @@ -7,6 +7,7 @@ using System.Diagnostics; using System.Linq; using JetBrains.Annotations; +using Microsoft.EntityFrameworkCore.ChangeTracking.Internal; using Microsoft.EntityFrameworkCore.Diagnostics; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.Extensions.DependencyInjection; @@ -61,6 +62,17 @@ public virtual IServiceProvider GetOrAdd([NotNull] IDbContextOptions options, bo return internalServiceProvider; } + if (coreOptionsExtension?.ServiceProviderCachingEnabled == false) + { + return BuildServiceProvider().ServiceProvider; + } + + var key = options.Extensions + .OrderBy(e => e.GetType().Name) + .Aggregate(0L, (t, e) => (t * 397) ^ ((long)e.GetType().GetHashCode() * 397) ^ e.Info.GetServiceProviderHashCode()); + + return _configurations.GetOrAdd(key, k => BuildServiceProvider()).ServiceProvider; + (IServiceProvider ServiceProvider, IDictionary DebugInfo) BuildServiceProvider() { ValidateOptions(options); @@ -137,22 +149,17 @@ public virtual IServiceProvider GetOrAdd([NotNull] IDbContextOptions options, bo _configurations.Values.Select(e => e.ServiceProvider).ToList()); } } + + var applicationServiceProvider = options.FindExtension()?.ApplicationServiceProvider; + if (applicationServiceProvider?.GetService() != null) + { + logger.RedundantAddServicesCallWarning(serviceProvider); + } } } return (serviceProvider, debugInfo); } - - if (coreOptionsExtension?.ServiceProviderCachingEnabled == false) - { - return BuildServiceProvider().ServiceProvider; - } - - var key = options.Extensions - .OrderBy(e => e.GetType().Name) - .Aggregate(0L, (t, e) => (t * 397) ^ ((long)e.GetType().GetHashCode() * 397) ^ e.Info.GetServiceProviderHashCode()); - - return _configurations.GetOrAdd(key, k => BuildServiceProvider()).ServiceProvider; } private static void ValidateOptions(IDbContextOptions options) diff --git a/src/EFCore/Properties/CoreStrings.Designer.cs b/src/EFCore/Properties/CoreStrings.Designer.cs index 4b58b9987f3..31c99fcc135 100644 --- a/src/EFCore/Properties/CoreStrings.Designer.cs +++ b/src/EFCore/Properties/CoreStrings.Designer.cs @@ -3893,5 +3893,29 @@ public static EventDefinition LogNonNullableReferenceOnDependent return (EventDefinition)definition; } + + /// + /// 'AddEntityFramework*' was called on the service provider, but 'UseInternalServiceProvider' wasn't called in the DbContext options configuration. Remove the 'AddEntityFramework*' call as in most cases it's not needed and might cause conflicts with other products and services registered in the same service provider. + /// + public static EventDefinition LogRedundantAddServicesCall([NotNull] IDiagnosticsLogger logger) + { + var definition = ((LoggingDefinitions)logger.Definitions).LogRedundantAddServicesCall; + if (definition == null) + { + definition = LazyInitializer.EnsureInitialized( + ref ((LoggingDefinitions)logger.Definitions).LogRedundantAddServicesCall, + () => new EventDefinition( + logger.Options, + CoreEventId.RedundantAddServicesCallWarning, + LogLevel.Warning, + "CoreEventId.RedundantAddServicesCallWarning", + level => LoggerMessage.Define( + level, + CoreEventId.RedundantAddServicesCallWarning, + _resourceManager.GetString("LogRedundantAddServicesCall")))); + } + + return (EventDefinition)definition; + } } } diff --git a/src/EFCore/Properties/CoreStrings.resx b/src/EFCore/Properties/CoreStrings.resx index 01ca87b509e..6a1c7c73281 100644 --- a/src/EFCore/Properties/CoreStrings.resx +++ b/src/EFCore/Properties/CoreStrings.resx @@ -1,17 +1,17 @@  - @@ -1223,6 +1223,10 @@ '{principalEntityType}.{principalNavigation}' may still be null at runtime despite being declared as non-nullable since only the navigation to principal can be configured as required. Debug CoreEventId.NonNullableReferenceOnDependent string string + + 'AddEntityFramework*' was called on the service provider, but 'UseInternalServiceProvider' wasn't called in the DbContext options configuration. Remove the 'AddEntityFramework*' call as in most cases it's not needed and might cause conflicts with other products and services registered in the same service provider. + Warning CoreEventId.RedundantAddServicesCallWarning + The type '{entityType}' cannot be marked as owned because the derived entity type - '{derivedType}' has been configured as non-owned. diff --git a/test/EFCore.Tests/ChangeTracking/ChangeTrackerTest.cs b/test/EFCore.Tests/ChangeTracking/ChangeTrackerTest.cs index 98ad71b09fc..61388349b2f 100644 --- a/test/EFCore.Tests/ChangeTracking/ChangeTrackerTest.cs +++ b/test/EFCore.Tests/ChangeTracking/ChangeTrackerTest.cs @@ -1081,10 +1081,8 @@ private static readonly IServiceProvider _sensitiveProvider private static readonly IServiceProvider _poolProvider = new ServiceCollection() - .AddEntityFrameworkInMemoryDatabase() .AddDbContextPool( - p => - p.UseInMemoryDatabase(nameof(LikeAZooContextPooled)) + p => p.UseInMemoryDatabase(nameof(LikeAZooContextPooled)) .UseInternalServiceProvider(InMemoryFixture.BuildServiceProvider(_loggerFactory))) .BuildServiceProvider(); diff --git a/test/EFCore.Tests/DbContextServicesTest.cs b/test/EFCore.Tests/DbContextServicesTest.cs index 0cd36bff436..823c2c7c78d 100644 --- a/test/EFCore.Tests/DbContextServicesTest.cs +++ b/test/EFCore.Tests/DbContextServicesTest.cs @@ -21,6 +21,7 @@ using Microsoft.Extensions.Caching.Memory; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Abstractions; using Xunit; // ReSharper disable ClassNeverInstantiated.Local @@ -89,7 +90,8 @@ public InfoLogContext(bool useLoggerFactory, bool configureForDebug) protected internal override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { - optionsBuilder.UseInMemoryDatabase(typeof(InfoLogContext).FullName); + optionsBuilder.UseInMemoryDatabase(typeof(InfoLogContext).FullName) + .ConfigureWarnings(w => w.Default(WarningBehavior.Throw)); if (_useLoggerFactory) { @@ -193,12 +195,15 @@ var serviceCollection if (pool) { serviceCollection.AddDbContextPool( - b => b.UseInMemoryDatabase("Scratch")); + b => b.UseInMemoryDatabase("Scratch") + .ConfigureWarnings(w => w.Default(WarningBehavior.Throw))); } else { serviceCollection.AddDbContext( - b => b.UseInMemoryDatabase("Scratch"), optionsLifetime: optionsLifetime); + b => b.UseInMemoryDatabase("Scratch") + .ConfigureWarnings(w => w.Default(WarningBehavior.Throw)), + optionsLifetime: optionsLifetime); } var appServiceProvider = serviceCollection.BuildServiceProvider(); @@ -312,7 +317,9 @@ public void Each_context_gets_new_scoped_services_with_explicit_config() var serviceProvider = InMemoryTestHelpers.Instance.CreateServiceProvider(); var options = new DbContextOptionsBuilder().UseInternalServiceProvider(serviceProvider) - .UseInMemoryDatabase(Guid.NewGuid().ToString()).Options; + .UseInMemoryDatabase(Guid.NewGuid().ToString()) + .ConfigureWarnings(w => w.Default(WarningBehavior.Throw)) + .Options; IServiceProvider contextServices; using (var context = new DbContext(options)) @@ -332,7 +339,8 @@ public void Each_context_gets_new_scoped_services_with_implicit_services_and_exp { var options = new DbContextOptionsBuilder() .UseInternalServiceProvider(InMemoryFixture.DefaultServiceProvider) - .UseInMemoryDatabase(Guid.NewGuid().ToString()).Options; + .UseInMemoryDatabase(Guid.NewGuid().ToString()) + .Options; IServiceProvider contextServices; using (var context = new DbContext(options)) @@ -609,6 +617,7 @@ public EarlyLearningCenter(IServiceProvider serviceProvider, DbContextOptions op protected internal override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) => optionsBuilder .UseInMemoryDatabase(Guid.NewGuid().ToString()) + .ConfigureWarnings(w => w.Default(WarningBehavior.Throw)) .UseInternalServiceProvider(_serviceProvider) .EnableServiceProviderCaching(false); @@ -695,6 +704,7 @@ public void Can_use_derived_context_with_options() { var options = new DbContextOptionsBuilder() .UseInMemoryDatabase(Guid.NewGuid().ToString()) + .ConfigureWarnings(w => w.Default(WarningBehavior.Throw)) .Options; var singleton = new object[3]; @@ -732,6 +742,7 @@ public void Can_use_derived_context_with_options_and_external_services() var options = new DbContextOptionsBuilder() .UseInMemoryDatabase(Guid.NewGuid().ToString()) + .ConfigureWarnings(w => w.Default(WarningBehavior.Throw)) .UseLoggerFactory(loggerFactory) .UseMemoryCache(memoryCache) .Options; @@ -794,6 +805,7 @@ public void Can_use_derived_context_controlling_internal_services_with_options() var options = new DbContextOptionsBuilder() .UseInMemoryDatabase(Guid.NewGuid().ToString()) + .ConfigureWarnings(w => w.Default(WarningBehavior.Throw)) .UseInternalServiceProvider(internalServiceProvider) .Options; @@ -825,6 +837,7 @@ public void Can_use_derived_context_with_options_no_OnConfiguring() { var options = new DbContextOptionsBuilder() .UseInMemoryDatabase(Guid.NewGuid().ToString()) + .ConfigureWarnings(w => w.Default(WarningBehavior.Throw)) .EnableServiceProviderCaching(false) .Options; @@ -862,6 +875,7 @@ public void Can_use_derived_context_with_options_and_external_services_no_OnConf var options = new DbContextOptionsBuilder() .UseInMemoryDatabase(Guid.NewGuid().ToString()) + .ConfigureWarnings(w => w.Default(WarningBehavior.Throw)) .UseLoggerFactory(loggerFactory) .UseMemoryCache(memoryCache) .EnableServiceProviderCaching(false) @@ -898,6 +912,7 @@ public void Can_use_derived_context_controlling_internal_services_with_options_n var options = new DbContextOptionsBuilder() .UseInMemoryDatabase(Guid.NewGuid().ToString()) + .ConfigureWarnings(w => w.Default(WarningBehavior.Throw)) .UseInternalServiceProvider(internalServiceProvider) .Options; @@ -968,6 +983,7 @@ public void Can_use_non_derived_context_with_options_and_external_services() .AddSingleton(loggerFactory) .AddSingleton(memoryCache))) .UseInMemoryDatabase(Guid.NewGuid().ToString()) + .ConfigureWarnings(w => w.Default(WarningBehavior.Throw)) .Options; IInMemoryStoreCache singleton; @@ -1002,6 +1018,7 @@ public void Can_use_non_derived_context_controlling_internal_services_with_optio var options = new DbContextOptionsBuilder() .UseInMemoryDatabase(Guid.NewGuid().ToString()) .UseInternalServiceProvider(internalServiceProvider) + .ConfigureWarnings(w => w.Default(WarningBehavior.Throw)) .Options; var singleton = new object[2]; @@ -1133,7 +1150,9 @@ public void Can_add_derived_context_with_options() { var appServiceProvider = new ServiceCollection() .AddDbContext( - (p, b) => b.UseInMemoryDatabase(Guid.NewGuid().ToString())) + (p, b) => b + .UseInMemoryDatabase(Guid.NewGuid().ToString()) + .ConfigureWarnings(w => w.Default(WarningBehavior.Throw))) .AddSingleton() .AddScoped() .BuildServiceProvider(); @@ -1186,7 +1205,9 @@ public void Can_add_derived_context_with_options() public void Can_add_derived_context_with_options_and_external_services() { var appServiceProvider = new ServiceCollection() - .AddDbContext(b => b.UseInMemoryDatabase(Guid.NewGuid().ToString())) + .AddDbContext(b => b + .UseInMemoryDatabase(Guid.NewGuid().ToString()) + .ConfigureWarnings(w => w.Default(WarningBehavior.Throw))) .BuildServiceProvider(); ILoggerFactory loggerFactory; @@ -1227,6 +1248,7 @@ public void Can_add_derived_context_with_options_and_external_services() public void Can_add_derived_context_controlling_internal_services() { var appServiceProvider = new ServiceCollection() + .AddLogging(l => l.AddProvider(new MyLoggerProvider())) .AddEntityFrameworkInMemoryDatabase() .AddDbContext() .BuildServiceProvider(); @@ -1260,12 +1282,14 @@ public void Can_add_derived_context_controlling_internal_services() public void Can_add_derived_context_controlling_internal_services_with_options() { var internalServiceProvider = new ServiceCollection() + .AddLogging(l => l.AddProvider(new MyLoggerProvider())) .AddEntityFrameworkInMemoryDatabase() .BuildServiceProvider(); var appServiceProvider = new ServiceCollection() .AddDbContext( b => b.UseInMemoryDatabase(Guid.NewGuid().ToString()) + .ConfigureWarnings(w => w.Default(WarningBehavior.Throw)) .UseInternalServiceProvider(internalServiceProvider)) .BuildServiceProvider(); @@ -1306,12 +1330,18 @@ public void Can_add_derived_context_one_service_provider_with_options(bool useIn if (useInterface) { serviceCollection.AddDbContext( - (p, b) => b.UseInMemoryDatabase(Guid.NewGuid().ToString()).UseInternalServiceProvider(p)); + (p, b) => b + .UseInMemoryDatabase(Guid.NewGuid().ToString()) + .ConfigureWarnings(w => w.Default(WarningBehavior.Throw)) + .UseInternalServiceProvider(p)); } else { serviceCollection.AddDbContext( - (p, b) => b.UseInMemoryDatabase(Guid.NewGuid().ToString()).UseInternalServiceProvider(p)); + (p, b) => b + .UseInMemoryDatabase(Guid.NewGuid().ToString()) + .ConfigureWarnings(w => w.Default(WarningBehavior.Throw)) + .UseInternalServiceProvider(p)); } var appServiceProvider = serviceCollection.BuildServiceProvider(); @@ -1355,7 +1385,10 @@ public void Can_add_derived_context_one_service_provider_with_options_and_extern var appServiceProvider = new ServiceCollection() .AddEntityFrameworkInMemoryDatabase() .AddDbContext( - (p, b) => b.UseInMemoryDatabase(Guid.NewGuid().ToString()).UseInternalServiceProvider(p), + (p, b) => b + .UseInMemoryDatabase(Guid.NewGuid().ToString()) + .ConfigureWarnings(w => w.Default(WarningBehavior.Throw)) + .UseInternalServiceProvider(p), ServiceLifetime.Scoped, singletonOptions ? ServiceLifetime.Singleton : ServiceLifetime.Scoped) .BuildServiceProvider(); @@ -1402,9 +1435,9 @@ public void Can_add_derived_context_with_options_no_OnConfiguring() { var appServiceProvider = new ServiceCollection() .AddDbContext( - b => - b.EnableServiceProviderCaching(false) - .UseInMemoryDatabase(Guid.NewGuid().ToString())) + b => b.EnableServiceProviderCaching(false) + .UseInMemoryDatabase(Guid.NewGuid().ToString()) + .ConfigureWarnings(w => w.Default(WarningBehavior.Throw))) .BuildServiceProvider(); var singleton = new object[3]; @@ -1439,9 +1472,9 @@ public void Can_add_derived_context_with_options_and_external_services_no_OnConf { var appServiceProvider = new ServiceCollection() .AddDbContext( - b => - b.EnableServiceProviderCaching(false) - .UseInMemoryDatabase(Guid.NewGuid().ToString())) + b =>b.EnableServiceProviderCaching(false) + .UseInMemoryDatabase(Guid.NewGuid().ToString()) + .ConfigureWarnings(w => w.Default(WarningBehavior.Throw))) .BuildServiceProvider(); ILoggerFactory loggerFactory; @@ -1486,6 +1519,7 @@ public void Can_add_derived_context_controlling_internal_services_with_options_n var appServiceProvider = new ServiceCollection() .AddDbContext( b => b.UseInMemoryDatabase(Guid.NewGuid().ToString()) + .ConfigureWarnings(w => w.Default(WarningBehavior.Throw)) .UseInternalServiceProvider(internalServiceProvider)) .BuildServiceProvider(); @@ -1522,7 +1556,10 @@ public void Can_add_derived_context_one_provider_with_options_no_OnConfiguring() var appServiceProvider = new ServiceCollection() .AddEntityFrameworkInMemoryDatabase() .AddDbContext( - (p, b) => b.UseInMemoryDatabase(Guid.NewGuid().ToString()).UseInternalServiceProvider(p)) + (p, b) => b + .UseInMemoryDatabase(Guid.NewGuid().ToString()) + .ConfigureWarnings(w => w.Default(WarningBehavior.Throw)) + .UseInternalServiceProvider(p)) .BuildServiceProvider(); var singleton = new object[3]; @@ -1558,7 +1595,10 @@ public void Can_add_derived_context_one_provider_with_options_and_external_servi var appServiceProvider = new ServiceCollection() .AddEntityFrameworkInMemoryDatabase() .AddDbContext( - (p, b) => b.UseInMemoryDatabase(Guid.NewGuid().ToString()).UseInternalServiceProvider(p)) + (p, b) => b + .UseInMemoryDatabase(Guid.NewGuid().ToString()) + .ConfigureWarnings(w => w.Default(WarningBehavior.Throw)) + .UseInternalServiceProvider(p)) .BuildServiceProvider(); var memoryCache = appServiceProvider.GetService(); @@ -1596,9 +1636,9 @@ public void Can_add_non_derived_context_with_options() { var appServiceProvider = new ServiceCollection() .AddDbContext( - b => - b.EnableServiceProviderCaching(false) - .UseInMemoryDatabase(Guid.NewGuid().ToString())) + b => b.EnableServiceProviderCaching(false) + .UseInMemoryDatabase(Guid.NewGuid().ToString()) + .ConfigureWarnings(w => w.Default(WarningBehavior.Throw))) .BuildServiceProvider(); var singleton = new object[4]; @@ -1635,6 +1675,7 @@ public void Can_add_non_derived_context_with_options_and_external_services() .AddDbContext( (p, b) => b.EnableServiceProviderCaching(false) .UseInMemoryDatabase(Guid.NewGuid().ToString()) + .ConfigureWarnings(w => w.Default(WarningBehavior.Throw)) .UseMemoryCache(p.GetService()) .UseLoggerFactory(p.GetService())) .AddMemoryCache() @@ -1676,7 +1717,10 @@ public void Can_add_non_derived_context_controlling_internal_services_with_optio { var appServiceProvider = new ServiceCollection() .AddEntityFrameworkInMemoryDatabase() - .AddDbContext((p, b) => b.UseInMemoryDatabase(Guid.NewGuid().ToString()).UseInternalServiceProvider(p)) + .AddDbContext((p, b) => b + .UseInMemoryDatabase(Guid.NewGuid().ToString()) + .ConfigureWarnings(w => w.Default(WarningBehavior.Throw)) + .UseInternalServiceProvider(p)) .BuildServiceProvider(); var singleton = new object[3]; @@ -1788,7 +1832,10 @@ public void Can_add_derived_context_as_singleton_controlling_internal_services(b ? new ServiceCollection() .AddEntityFrameworkInMemoryDatabase() .AddDbContext( - (p, b) => b.UseInternalServiceProvider(p).UseInMemoryDatabase(Guid.NewGuid().ToString()), + (p, b) => b + .UseInternalServiceProvider(p) + .UseInMemoryDatabase(Guid.NewGuid().ToString()) + .ConfigureWarnings(w => w.Default(WarningBehavior.Throw)), ServiceLifetime.Singleton) .BuildServiceProvider() : (addSingletonFirst @@ -1796,12 +1843,18 @@ public void Can_add_derived_context_as_singleton_controlling_internal_services(b .AddEntityFrameworkInMemoryDatabase() .AddSingleton() .AddDbContext( - (p, b) => b.UseInternalServiceProvider(p).UseInMemoryDatabase(Guid.NewGuid().ToString())) + (p, b) => b + .UseInternalServiceProvider(p) + .UseInMemoryDatabase(Guid.NewGuid().ToString()) + .ConfigureWarnings(w => w.Default(WarningBehavior.Throw))) .BuildServiceProvider() : new ServiceCollection() .AddEntityFrameworkInMemoryDatabase() .AddDbContext( - (p, b) => b.UseInternalServiceProvider(p).UseInMemoryDatabase(Guid.NewGuid().ToString())) + (p, b) => b + .UseInternalServiceProvider(p) + .UseInMemoryDatabase(Guid.NewGuid().ToString()) + .ConfigureWarnings(w => w.Default(WarningBehavior.Throw))) .AddSingleton() .BuildServiceProvider()); @@ -1939,7 +1992,10 @@ public void Can_add_derived_context_as_transient_controlling_internal_services(b ? new ServiceCollection() .AddEntityFrameworkInMemoryDatabase() .AddDbContext( - (p, b) => b.UseInternalServiceProvider(p).UseInMemoryDatabase(Guid.NewGuid().ToString()), + (p, b) => b + .UseInternalServiceProvider(p) + .UseInMemoryDatabase(Guid.NewGuid().ToString()) + .ConfigureWarnings(w => w.Default(WarningBehavior.Throw)), ServiceLifetime.Transient) .BuildServiceProvider() : (addTransientFirst @@ -1947,12 +2003,18 @@ public void Can_add_derived_context_as_transient_controlling_internal_services(b .AddEntityFrameworkInMemoryDatabase() .AddTransient() .AddDbContext( - (p, b) => b.UseInternalServiceProvider(p).UseInMemoryDatabase(Guid.NewGuid().ToString())) + (p, b) => b + .UseInternalServiceProvider(p) + .UseInMemoryDatabase(Guid.NewGuid().ToString()) + .ConfigureWarnings(w => w.Default(WarningBehavior.Throw))) .BuildServiceProvider() : new ServiceCollection() .AddEntityFrameworkInMemoryDatabase() .AddDbContext( - (p, b) => b.UseInternalServiceProvider(p).UseInMemoryDatabase(Guid.NewGuid().ToString())) + (p, b) => b + .UseInternalServiceProvider(p) + .UseInMemoryDatabase(Guid.NewGuid().ToString()) + .ConfigureWarnings(w => w.Default(WarningBehavior.Throw))) .AddTransient() .BuildServiceProvider()); @@ -2003,15 +2065,15 @@ public void Can_add_non_derived_context_as_singleton(bool addSingletonFirst) ? new ServiceCollection() .AddSingleton() .AddDbContext( - b => - b.EnableServiceProviderCaching(false) - .UseInMemoryDatabase(Guid.NewGuid().ToString())) + b => b.EnableServiceProviderCaching(false) + .UseInMemoryDatabase(Guid.NewGuid().ToString()) + .ConfigureWarnings(w => w.Default(WarningBehavior.Throw))) .BuildServiceProvider() : new ServiceCollection() .AddDbContext( - b => - b.EnableServiceProviderCaching(false) - .UseInMemoryDatabase(Guid.NewGuid().ToString())) + b => b.EnableServiceProviderCaching(false) + .UseInMemoryDatabase(Guid.NewGuid().ToString()) + .ConfigureWarnings(w => w.Default(WarningBehavior.Throw))) .AddSingleton() .BuildServiceProvider(); @@ -2067,12 +2129,18 @@ public void Can_add_non_derived_context_as_singleton_controlling_internal_servic { serviceCollection .AddSingleton() - .AddDbContext((p, b) => b.UseInMemoryDatabase(Guid.NewGuid().ToString()).UseInternalServiceProvider(p)); + .AddDbContext((p, b) => b + .UseInMemoryDatabase(Guid.NewGuid().ToString()) + .ConfigureWarnings(w => w.Default(WarningBehavior.Throw)) + .UseInternalServiceProvider(p)); } else { serviceCollection - .AddDbContext((p, b) => b.UseInMemoryDatabase(Guid.NewGuid().ToString()).UseInternalServiceProvider(p)) + .AddDbContext((p, b) => b + .UseInMemoryDatabase(Guid.NewGuid().ToString()) + .ConfigureWarnings(w => w.Default(WarningBehavior.Throw)) + .UseInternalServiceProvider(p)) .AddSingleton(); } @@ -2126,15 +2194,15 @@ public void Can_add_non_derived_context_as_transient(bool addTransientFirst) ? new ServiceCollection() .AddTransient() .AddDbContext( - b => - b.EnableServiceProviderCaching(false) - .UseInMemoryDatabase(Guid.NewGuid().ToString())) + b => b.EnableServiceProviderCaching(false) + .UseInMemoryDatabase(Guid.NewGuid().ToString()) + .ConfigureWarnings(w => w.Default(WarningBehavior.Throw))) .BuildServiceProvider() : new ServiceCollection() .AddDbContext( - b => - b.EnableServiceProviderCaching(false) - .UseInMemoryDatabase(Guid.NewGuid().ToString())) + b => b.EnableServiceProviderCaching(false) + .UseInMemoryDatabase(Guid.NewGuid().ToString()) + .ConfigureWarnings(w => w.Default(WarningBehavior.Throw))) .AddTransient() .BuildServiceProvider(); @@ -2194,12 +2262,18 @@ public void Can_add_non_derived_context_as_transient_controlling_internal_servic { serviceCollection .AddTransient() - .AddDbContext((p, b) => b.UseInMemoryDatabase(Guid.NewGuid().ToString()).UseInternalServiceProvider(p)); + .AddDbContext((p, b) => b + .UseInMemoryDatabase(Guid.NewGuid().ToString()) + .ConfigureWarnings(w => w.Default(WarningBehavior.Throw)) + .UseInternalServiceProvider(p)); } else { serviceCollection - .AddDbContext((p, b) => b.UseInMemoryDatabase(Guid.NewGuid().ToString()).UseInternalServiceProvider(p)) + .AddDbContext((p, b) => b + .UseInMemoryDatabase(Guid.NewGuid().ToString()) + .ConfigureWarnings(w => w.Default(WarningBehavior.Throw)) + .UseInternalServiceProvider(p)) .AddTransient(); } @@ -2253,7 +2327,10 @@ public void Can_use_logger_before_context_exists_and_after_disposed() { var appServiceProvider = new ServiceCollection() .AddEntityFrameworkInMemoryDatabase() - .AddDbContext((p, b) => b.UseInMemoryDatabase(Guid.NewGuid().ToString()).UseInternalServiceProvider(p)) + .AddDbContext((p, b) => b + .UseInMemoryDatabase(Guid.NewGuid().ToString()) + .ConfigureWarnings(w => w.Default(WarningBehavior.Throw)) + .UseInternalServiceProvider(p)) .BuildServiceProvider(); Assert.NotNull(appServiceProvider.GetService>()); @@ -2275,8 +2352,10 @@ public void Can_use_logger_before_context_exists_and_after_disposed() public void Can_use_logger_before_context_exists_and_after_disposed_when_logger_factory_replaced() { WrappingLoggerFactory loggerFactory = null; + Log.Clear(); var appServiceProvider = new ServiceCollection() + .AddLogging(l => l.AddProvider(new MyLoggerProvider())) .AddEntityFrameworkInMemoryDatabase() .AddDbContext( (p, b) => @@ -2294,6 +2373,9 @@ public void Can_use_logger_before_context_exists_and_after_disposed_when_logger_ { var context = serviceScope.ServiceProvider.GetService(); + var redundantServicesWarning = Log.Single(e => e.Id.Id == CoreEventId.RedundantAddServicesCallWarning.Id); + Assert.Equal(LogLevel.Warning, redundantServicesWarning.Level); + Assert.NotNull(context.Model); Assert.NotNull(context.GetService>()); @@ -2311,7 +2393,10 @@ public void Can_use_memory_cache_before_context_exists_and_after_disposed() { var appServiceProvider = new ServiceCollection() .AddEntityFrameworkInMemoryDatabase() - .AddDbContext((p, b) => b.UseInMemoryDatabase(Guid.NewGuid().ToString()).UseInternalServiceProvider(p)) + .AddDbContext((p, b) => b + .UseInMemoryDatabase(Guid.NewGuid().ToString()) + .ConfigureWarnings(w => w.Default(WarningBehavior.Throw)) + .UseInternalServiceProvider(p)) .BuildServiceProvider(); var memoryCache = appServiceProvider.GetService(); @@ -2338,6 +2423,7 @@ public void Can_use_memory_cache_before_context_exists_and_after_disposed_when_l .AddDbContext( (p, b) => b.UseInMemoryDatabase(Guid.NewGuid().ToString()) + .ConfigureWarnings(w => w.Default(WarningBehavior.Throw)) .EnableServiceProviderCaching(false) .UseMemoryCache(replacecMemoryCache)) .BuildServiceProvider(); @@ -2599,7 +2685,8 @@ protected internal override void OnConfiguring(DbContextOptionsBuilder optionsBu .ReplaceService() .ReplaceService() .EnableServiceProviderCaching(false) - .UseInMemoryDatabase(Guid.NewGuid().ToString()); + .UseInMemoryDatabase(Guid.NewGuid().ToString()) + .ConfigureWarnings(w => w.Default(WarningBehavior.Throw)); } private class CustomModelCustomizer : ModelCustomizer @@ -2633,6 +2720,7 @@ public void Can_replace_services_in_passed_options() { var options = new DbContextOptionsBuilder() .UseInMemoryDatabase(Guid.NewGuid().ToString()) + .ConfigureWarnings(w => w.Default(WarningBehavior.Throw)) .ReplaceService() .ReplaceService() .ReplaceService() @@ -2671,7 +2759,8 @@ public void Can_replace_services_using_AddDbContext() b => b.ReplaceService() .ReplaceService() .ReplaceService() - .UseInMemoryDatabase(Guid.NewGuid().ToString())) + .UseInMemoryDatabase(Guid.NewGuid().ToString()) + .ConfigureWarnings(w => w.Default(WarningBehavior.Throw))) .BuildServiceProvider(); object replacedSingleton; @@ -2724,6 +2813,7 @@ private class ReplaceServiceContext2 : DbContext protected internal override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) => optionsBuilder .ReplaceService() + .ConfigureWarnings(w => w.Default(WarningBehavior.Throw)) .UseInternalServiceProvider( new ServiceCollection() .AddEntityFrameworkInMemoryDatabase() @@ -2736,6 +2826,7 @@ public void Throws_replacing_services_in_options_when_UseInternalServiceProvider { var options = new DbContextOptionsBuilder() .UseInMemoryDatabase(Guid.NewGuid().ToString()) + .ConfigureWarnings(w => w.Default(WarningBehavior.Throw)) .UseInternalServiceProvider( new ServiceCollection() .AddEntityFrameworkInMemoryDatabase() @@ -2757,6 +2848,7 @@ public void Throws_replacing_services_with_AddDbContext_when_UseInternalServiceP .AddDbContext( (p, b) => b.ReplaceService() .UseInMemoryDatabase(Guid.NewGuid().ToString()) + .ConfigureWarnings(w => w.Default(WarningBehavior.Throw)) .UseInternalServiceProvider(p)) .BuildServiceProvider();