diff --git a/src/EFCore.Cosmos/Infrastructure/CosmosModelCustomizer.cs b/src/EFCore.Cosmos/Infrastructure/CosmosModelCustomizer.cs index bb519e5fab4..89d80143214 100644 --- a/src/EFCore.Cosmos/Infrastructure/CosmosModelCustomizer.cs +++ b/src/EFCore.Cosmos/Infrastructure/CosmosModelCustomizer.cs @@ -7,14 +7,9 @@ namespace Microsoft.EntityFrameworkCore.Cosmos.Infrastructure { /// - /// - /// Builds the model for a given context. This default implementation builds the model by calling - /// on the context. - /// - /// - /// This type is typically used by database providers (and other extensions). It is generally - /// not used in application code. - /// + /// Builds the model for a given context. This implementation builds the model by calling + /// on the context and + /// using the context type name as the default container name. /// public class CosmosModelCustomizer : ModelCustomizer { diff --git a/src/EFCore.Cosmos/Metadata/Conventions/Internal/CosmosDiscriminatorConvention.cs b/src/EFCore.Cosmos/Metadata/Conventions/CosmosDiscriminatorConvention.cs similarity index 94% rename from src/EFCore.Cosmos/Metadata/Conventions/Internal/CosmosDiscriminatorConvention.cs rename to src/EFCore.Cosmos/Metadata/Conventions/CosmosDiscriminatorConvention.cs index 91c8bf65cf2..05b56c7ebda 100644 --- a/src/EFCore.Cosmos/Metadata/Conventions/Internal/CosmosDiscriminatorConvention.cs +++ b/src/EFCore.Cosmos/Metadata/Conventions/CosmosDiscriminatorConvention.cs @@ -2,14 +2,13 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using JetBrains.Annotations; -using Microsoft.EntityFrameworkCore.Diagnostics; using Microsoft.EntityFrameworkCore.Internal; using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Metadata.Builders; using Microsoft.EntityFrameworkCore.Metadata.Conventions; -using Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal; +using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure; -namespace Microsoft.EntityFrameworkCore.Cosmos.Metadata.Conventions.Internal +namespace Microsoft.EntityFrameworkCore.Cosmos.Metadata.Conventions { /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -25,8 +24,8 @@ public class CosmosDiscriminatorConvention : DiscriminatorConvention, IEntityTyp /// 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 CosmosDiscriminatorConvention([NotNull] IDiagnosticsLogger logger) - : base(logger) + public CosmosDiscriminatorConvention([NotNull] ProviderConventionSetBuilderDependencies dependencies) + : base(dependencies) { } diff --git a/src/EFCore.Cosmos/Metadata/Conventions/Internal/CosmosConventionSetBuilder.cs b/src/EFCore.Cosmos/Metadata/Conventions/Internal/CosmosConventionSetBuilder.cs index 629f9462684..e25e467643e 100644 --- a/src/EFCore.Cosmos/Metadata/Conventions/Internal/CosmosConventionSetBuilder.cs +++ b/src/EFCore.Cosmos/Metadata/Conventions/Internal/CosmosConventionSetBuilder.cs @@ -4,7 +4,6 @@ using JetBrains.Annotations; using Microsoft.EntityFrameworkCore.Metadata.Conventions; using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure; -using Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal; namespace Microsoft.EntityFrameworkCore.Cosmos.Metadata.Conventions.Internal { @@ -20,8 +19,8 @@ public override ConventionSet CreateConventionSet() { var conventionSet = base.CreateConventionSet(); - var discriminatorConvention = new CosmosDiscriminatorConvention(Dependencies.Logger); - var storeKeyConvention = new StoreKeyConvention(); + var discriminatorConvention = new CosmosDiscriminatorConvention(Dependencies); + var storeKeyConvention = new StoreKeyConvention(Dependencies); conventionSet.EntityTypeAddedConventions.Add(storeKeyConvention); conventionSet.EntityTypeAddedConventions.Add(discriminatorConvention); diff --git a/src/EFCore.Cosmos/Metadata/Conventions/Internal/StoreKeyConvention.cs b/src/EFCore.Cosmos/Metadata/Conventions/StoreKeyConvention.cs similarity index 91% rename from src/EFCore.Cosmos/Metadata/Conventions/Internal/StoreKeyConvention.cs rename to src/EFCore.Cosmos/Metadata/Conventions/StoreKeyConvention.cs index 72aa25245e2..41bb656fbc5 100644 --- a/src/EFCore.Cosmos/Metadata/Conventions/Internal/StoreKeyConvention.cs +++ b/src/EFCore.Cosmos/Metadata/Conventions/StoreKeyConvention.cs @@ -1,14 +1,16 @@ // 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 JetBrains.Annotations; using Microsoft.EntityFrameworkCore.Cosmos.Metadata.Internal; using Microsoft.EntityFrameworkCore.Cosmos.ValueGeneration.Internal; using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Metadata.Builders; using Microsoft.EntityFrameworkCore.Metadata.Conventions; +using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure; using Newtonsoft.Json.Linq; -namespace Microsoft.EntityFrameworkCore.Cosmos.Metadata.Conventions.Internal +namespace Microsoft.EntityFrameworkCore.Cosmos.Metadata.Conventions { public class StoreKeyConvention : IEntityTypeAddedConvention, @@ -19,6 +21,16 @@ public class StoreKeyConvention : public static readonly string IdPropertyName = "id"; public static readonly string JObjectPropertyName = "__jObject"; + public StoreKeyConvention([NotNull] ProviderConventionSetBuilderDependencies dependencies) + { + Dependencies = dependencies; + } + + /// + /// Parameter object containing service dependencies. + /// + protected virtual ProviderConventionSetBuilderDependencies Dependencies { get; } + private static void Process(IConventionEntityTypeBuilder entityTypeBuilder) { var entityType = entityTypeBuilder.Metadata; diff --git a/src/EFCore.Cosmos/Query/Internal/ValueBufferFactoryFactory.cs b/src/EFCore.Cosmos/Query/Internal/ValueBufferFactoryFactory.cs index 78ede33623a..728f6c47e79 100644 --- a/src/EFCore.Cosmos/Query/Internal/ValueBufferFactoryFactory.cs +++ b/src/EFCore.Cosmos/Query/Internal/ValueBufferFactoryFactory.cs @@ -6,7 +6,7 @@ using System.Linq; using System.Linq.Expressions; using System.Reflection; -using Microsoft.EntityFrameworkCore.Cosmos.Metadata.Conventions.Internal; +using Microsoft.EntityFrameworkCore.Cosmos.Metadata.Conventions; using Microsoft.EntityFrameworkCore.Metadata; using Newtonsoft.Json.Linq; using Remotion.Linq.Parsing.ExpressionVisitors; diff --git a/src/EFCore.Cosmos/Storage/Internal/CosmosDatabaseWrapper.cs b/src/EFCore.Cosmos/Storage/Internal/CosmosDatabaseWrapper.cs index 766877ca6a2..8d9b101f1c5 100644 --- a/src/EFCore.Cosmos/Storage/Internal/CosmosDatabaseWrapper.cs +++ b/src/EFCore.Cosmos/Storage/Internal/CosmosDatabaseWrapper.cs @@ -8,12 +8,11 @@ using System.Threading.Tasks; using Microsoft.EntityFrameworkCore.ChangeTracking.Internal; using Microsoft.EntityFrameworkCore.Cosmos.Internal; -using Microsoft.EntityFrameworkCore.Cosmos.Metadata.Conventions.Internal; +using Microsoft.EntityFrameworkCore.Cosmos.Metadata.Conventions; using Microsoft.EntityFrameworkCore.Cosmos.Metadata.Internal; using Microsoft.EntityFrameworkCore.Cosmos.Update.Internal; using Microsoft.EntityFrameworkCore.Diagnostics; using Microsoft.EntityFrameworkCore.Metadata; -using Microsoft.EntityFrameworkCore.Metadata.Internal; using Microsoft.EntityFrameworkCore.Storage; using Microsoft.EntityFrameworkCore.Update; using Newtonsoft.Json.Linq; diff --git a/src/EFCore.Cosmos/Update/Internal/DocumentSource.cs b/src/EFCore.Cosmos/Update/Internal/DocumentSource.cs index a7e54611856..fa76f01ecb3 100644 --- a/src/EFCore.Cosmos/Update/Internal/DocumentSource.cs +++ b/src/EFCore.Cosmos/Update/Internal/DocumentSource.cs @@ -3,7 +3,7 @@ using System.Collections; using Microsoft.EntityFrameworkCore.ChangeTracking.Internal; -using Microsoft.EntityFrameworkCore.Cosmos.Metadata.Conventions.Internal; +using Microsoft.EntityFrameworkCore.Cosmos.Metadata.Conventions; using Microsoft.EntityFrameworkCore.Cosmos.Metadata.Internal; using Microsoft.EntityFrameworkCore.Cosmos.Storage.Internal; using Microsoft.EntityFrameworkCore.Metadata; diff --git a/src/EFCore.Design/Migrations/Design/CSharpSnapshotGenerator.cs b/src/EFCore.Design/Migrations/Design/CSharpSnapshotGenerator.cs index ec3e743f4fe..8f19a86fea8 100644 --- a/src/EFCore.Design/Migrations/Design/CSharpSnapshotGenerator.cs +++ b/src/EFCore.Design/Migrations/Design/CSharpSnapshotGenerator.cs @@ -11,7 +11,7 @@ using Microsoft.EntityFrameworkCore.Internal; using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Metadata.Builders; -using Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal; +using Microsoft.EntityFrameworkCore.Metadata.Conventions; using Microsoft.EntityFrameworkCore.Metadata.Internal; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; using Microsoft.EntityFrameworkCore.Utilities; @@ -761,9 +761,9 @@ protected virtual void GenerateEntityTypeAnnotations( IgnoreAnnotations( annotations, - RelationshipDiscoveryConvention.NavigationCandidatesAnnotationName, - RelationshipDiscoveryConvention.AmbiguousNavigationsAnnotationName, - InversePropertyAttributeConvention.InverseNavigationsAnnotationName, + CoreAnnotationNames.NavigationCandidates, + CoreAnnotationNames.AmbiguousNavigations, + CoreAnnotationNames.InverseNavigations, CoreAnnotationNames.NavigationAccessMode, CoreAnnotationNames.PropertyAccessMode, CoreAnnotationNames.ChangeTrackingStrategy, diff --git a/src/EFCore.Design/Migrations/Design/MigrationsCodeGenerator.cs b/src/EFCore.Design/Migrations/Design/MigrationsCodeGenerator.cs index 234d537971d..52ad6168ab9 100644 --- a/src/EFCore.Design/Migrations/Design/MigrationsCodeGenerator.cs +++ b/src/EFCore.Design/Migrations/Design/MigrationsCodeGenerator.cs @@ -9,7 +9,7 @@ using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Internal; using Microsoft.EntityFrameworkCore.Metadata; -using Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal; +using Microsoft.EntityFrameworkCore.Metadata.Conventions; using Microsoft.EntityFrameworkCore.Metadata.Internal; using Microsoft.EntityFrameworkCore.Migrations.Operations; using Microsoft.EntityFrameworkCore.Utilities; @@ -219,9 +219,9 @@ private static IEnumerable GetAnnotationNamespaces(IEnumerable { - RelationshipDiscoveryConvention.NavigationCandidatesAnnotationName, - RelationshipDiscoveryConvention.AmbiguousNavigationsAnnotationName, - InversePropertyAttributeConvention.InverseNavigationsAnnotationName, + CoreAnnotationNames.NavigationCandidates, + CoreAnnotationNames.AmbiguousNavigations, + CoreAnnotationNames.InverseNavigations, ChangeDetector.SkipDetectChangesAnnotation, CoreAnnotationNames.OwnedTypes, CoreAnnotationNames.ChangeTrackingStrategy, diff --git a/src/EFCore.Design/Scaffolding/Internal/CSharpDbContextGenerator.cs b/src/EFCore.Design/Scaffolding/Internal/CSharpDbContextGenerator.cs index 7f2249b9628..5ebd575a8b4 100644 --- a/src/EFCore.Design/Scaffolding/Internal/CSharpDbContextGenerator.cs +++ b/src/EFCore.Design/Scaffolding/Internal/CSharpDbContextGenerator.cs @@ -13,6 +13,7 @@ using Microsoft.EntityFrameworkCore.Internal; using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Microsoft.EntityFrameworkCore.Metadata.Conventions; using Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal; using Microsoft.EntityFrameworkCore.Metadata.Internal; using Microsoft.EntityFrameworkCore.Utilities; @@ -67,7 +68,13 @@ public CSharpDbContextGenerator( /// 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 virtual string WriteCode(IModel model, string @namespace, string contextName, string connectionString, bool useDataAnnotations, bool suppressConnectionStringWarning) + public virtual string WriteCode( + IModel model, + string @namespace, + string contextName, + string connectionString, + bool useDataAnnotations, + bool suppressConnectionStringWarning) { Check.NotNull(model, nameof(model)); @@ -683,16 +690,10 @@ private void GenerateProperty(IProperty property, bool useDataAnnotations) $"({_code.Literal(property.GetComputedColumnSql())})"); } - var dummyLogger = new DiagnosticsLogger( - new ScopedLoggerFactory(new LoggerFactory(), dispose: true), - new LoggingOptions(), - new DiagnosticListener(""), - _loggingDefinitions); - var valueGenerated = property.ValueGenerated; var isRowVersion = false; if (((IConventionProperty)property).GetValueGeneratedConfigurationSource().HasValue - && new RelationalValueGeneratorConvention(dummyLogger).GetValueGenerated((IConventionProperty)property) != valueGenerated) + && RelationalValueGeneratorConvention.GetValueGenerated(property) != valueGenerated) { string methodName; switch (valueGenerated) diff --git a/src/EFCore.Design/Scaffolding/Internal/CSharpEntityTypeGenerator.cs b/src/EFCore.Design/Scaffolding/Internal/CSharpEntityTypeGenerator.cs index 387d896c661..0e623774adb 100644 --- a/src/EFCore.Design/Scaffolding/Internal/CSharpEntityTypeGenerator.cs +++ b/src/EFCore.Design/Scaffolding/Internal/CSharpEntityTypeGenerator.cs @@ -11,7 +11,7 @@ using Microsoft.EntityFrameworkCore.Design.Internal; using Microsoft.EntityFrameworkCore.Internal; using Microsoft.EntityFrameworkCore.Metadata; -using Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal; +using Microsoft.EntityFrameworkCore.Metadata.Conventions; using Microsoft.EntityFrameworkCore.Metadata.Internal; using Microsoft.EntityFrameworkCore.Utilities; diff --git a/src/EFCore.Design/Scaffolding/Internal/RelationalScaffoldingModelFactory.cs b/src/EFCore.Design/Scaffolding/Internal/RelationalScaffoldingModelFactory.cs index a7181e50a54..f9977387931 100644 --- a/src/EFCore.Design/Scaffolding/Internal/RelationalScaffoldingModelFactory.cs +++ b/src/EFCore.Design/Scaffolding/Internal/RelationalScaffoldingModelFactory.cs @@ -3,7 +3,6 @@ using System; using System.Collections.Generic; -using System.Diagnostics; using System.Globalization; using System.Linq; using JetBrains.Annotations; @@ -20,7 +19,6 @@ using Microsoft.EntityFrameworkCore.Scaffolding.Metadata; using Microsoft.EntityFrameworkCore.Scaffolding.Metadata.Internal; using Microsoft.EntityFrameworkCore.Utilities; -using Microsoft.Extensions.Logging; namespace Microsoft.EntityFrameworkCore.Scaffolding.Internal { @@ -516,13 +514,7 @@ protected virtual KeyBuilder VisitPrimaryKey([NotNull] EntityTypeBuilder builder var property = builder.Metadata.FindProperty(GetPropertyName(primaryKey.Columns[0]))?.AsProperty(); if (property != null) { - var dummyLogger = new DiagnosticsLogger( - new ScopedLoggerFactory(new LoggerFactory(), dispose: true), - new LoggingOptions(), - new DiagnosticListener(""), - _loggingDefinitions); - - var conventionalValueGenerated = new RelationalValueGeneratorConvention(dummyLogger).GetValueGenerated(property); + var conventionalValueGenerated = RelationalValueGeneratorConvention.GetValueGenerated(property); if (conventionalValueGenerated == ValueGenerated.OnAdd) { property.ValueGenerated = ValueGenerated.Never; diff --git a/src/EFCore.Proxies/Proxies/Internal/ProxiesConventionSetCustomizer.cs b/src/EFCore.Proxies/Proxies/Internal/ProxiesConventionSetCustomizer.cs index 02e7347405d..503504b9900 100644 --- a/src/EFCore.Proxies/Proxies/Internal/ProxiesConventionSetCustomizer.cs +++ b/src/EFCore.Proxies/Proxies/Internal/ProxiesConventionSetCustomizer.cs @@ -2,7 +2,6 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using JetBrains.Annotations; -using Microsoft.EntityFrameworkCore.Diagnostics; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Metadata.Conventions; @@ -29,9 +28,8 @@ namespace Microsoft.EntityFrameworkCore.Proxies.Internal public class ProxiesConventionSetCustomizer : IConventionSetCustomizer { private readonly IDbContextOptions _options; - private readonly IConstructorBindingFactory _constructorBindingFactory; private readonly IProxyFactory _proxyFactory; - private readonly IDiagnosticsLogger _logger; + private readonly ProviderConventionSetBuilderDependencies _conventionSetBuilderDependencies; private readonly LazyLoaderParameterBindingFactoryDependencies _lazyLoaderParameterBindingFactoryDependencies; /// @@ -41,17 +39,15 @@ public class ProxiesConventionSetCustomizer : IConventionSetCustomizer /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public ProxiesConventionSetCustomizer( - [NotNull] IDbContextOptions options, - [NotNull] IConstructorBindingFactory constructorBindingFactory, [NotNull] IProxyFactory proxyFactory, - [NotNull] IDiagnosticsLogger logger, - [NotNull] LazyLoaderParameterBindingFactoryDependencies lazyLoaderParameterBindingFactoryDependencies) + [NotNull] IDbContextOptions options, + [NotNull] LazyLoaderParameterBindingFactoryDependencies lazyLoaderParameterBindingFactoryDependencies, + [NotNull] ProviderConventionSetBuilderDependencies conventionSetBuilderDependencies) { - _options = options; - _constructorBindingFactory = constructorBindingFactory; _proxyFactory = proxyFactory; - _logger = logger; + _options = options; _lazyLoaderParameterBindingFactoryDependencies = lazyLoaderParameterBindingFactoryDependencies; + _conventionSetBuilderDependencies = conventionSetBuilderDependencies; } /// @@ -62,13 +58,14 @@ public ProxiesConventionSetCustomizer( /// public virtual ConventionSet ModifyConventions(ConventionSet conventionSet) { - conventionSet.ModelFinalizedConventions.Add( + ConventionSet.AddBefore( + conventionSet.ModelFinalizedConventions, new ProxyBindingRewriter( - _lazyLoaderParameterBindingFactoryDependencies, _proxyFactory, - _constructorBindingFactory, - _logger, - _options.FindExtension())); + _options.FindExtension(), + _lazyLoaderParameterBindingFactoryDependencies, + _conventionSetBuilderDependencies), + typeof(ValidatingConvention)); return conventionSet; } diff --git a/src/EFCore.Proxies/Proxies/Internal/ProxyBindingRewriter.cs b/src/EFCore.Proxies/Proxies/Internal/ProxyBindingRewriter.cs index 147c96370b9..e81a36719e4 100644 --- a/src/EFCore.Proxies/Proxies/Internal/ProxyBindingRewriter.cs +++ b/src/EFCore.Proxies/Proxies/Internal/ProxyBindingRewriter.cs @@ -6,13 +6,12 @@ using System.Linq; using System.Reflection; using JetBrains.Annotations; -using Microsoft.EntityFrameworkCore.Diagnostics; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Internal; using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Metadata.Builders; using Microsoft.EntityFrameworkCore.Metadata.Conventions; -using Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal; +using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure; using Microsoft.EntityFrameworkCore.Metadata.Internal; namespace Microsoft.EntityFrameworkCore.Proxies.Internal @@ -43,16 +42,15 @@ private static readonly PropertyInfo _lazyLoaderProperty /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public ProxyBindingRewriter( - [NotNull] LazyLoaderParameterBindingFactoryDependencies lazyLoaderParameterBindingFactoryDependencies, [NotNull] IProxyFactory proxyFactory, - [NotNull] IConstructorBindingFactory bindingFactory, - [NotNull] IDiagnosticsLogger logger, - [CanBeNull] ProxiesOptionsExtension options) + [CanBeNull] ProxiesOptionsExtension options, + [NotNull] LazyLoaderParameterBindingFactoryDependencies lazyLoaderParameterBindingFactoryDependencies, + [NotNull] ProviderConventionSetBuilderDependencies conventionSetBuilderDependencies) { - _directBindingConvention = new ConstructorBindingConvention(bindingFactory, logger); - _lazyLoaderParameterBindingFactoryDependencies = lazyLoaderParameterBindingFactoryDependencies; _proxyFactory = proxyFactory; _options = options; + _lazyLoaderParameterBindingFactoryDependencies = lazyLoaderParameterBindingFactoryDependencies; + _directBindingConvention = new ConstructorBindingConvention(conventionSetBuilderDependencies); } /// diff --git a/src/EFCore.Relational/Extensions/RelationalForeignKeyBuilderExtensions.cs b/src/EFCore.Relational/Extensions/RelationalForeignKeyBuilderExtensions.cs index bc8b8d81f86..1e730ec7d04 100644 --- a/src/EFCore.Relational/Extensions/RelationalForeignKeyBuilderExtensions.cs +++ b/src/EFCore.Relational/Extensions/RelationalForeignKeyBuilderExtensions.cs @@ -2,8 +2,8 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using JetBrains.Annotations; +using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Metadata.Builders; -using Microsoft.EntityFrameworkCore.Metadata.Internal; using Microsoft.EntityFrameworkCore.Utilities; // ReSharper disable once CheckNamespace diff --git a/src/EFCore.Relational/Extensions/RelationalForeignKeyExtensions.cs b/src/EFCore.Relational/Extensions/RelationalForeignKeyExtensions.cs index 36789d56706..f869b6b2e27 100644 --- a/src/EFCore.Relational/Extensions/RelationalForeignKeyExtensions.cs +++ b/src/EFCore.Relational/Extensions/RelationalForeignKeyExtensions.cs @@ -6,7 +6,6 @@ using JetBrains.Annotations; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Metadata; -using Microsoft.EntityFrameworkCore.Metadata.Internal; using Microsoft.EntityFrameworkCore.Utilities; // ReSharper disable once CheckNamespace diff --git a/src/EFCore.Relational/Extensions/RelationalIndexBuilderExtensions.cs b/src/EFCore.Relational/Extensions/RelationalIndexBuilderExtensions.cs index e805a4ef103..bfc5f734de1 100644 --- a/src/EFCore.Relational/Extensions/RelationalIndexBuilderExtensions.cs +++ b/src/EFCore.Relational/Extensions/RelationalIndexBuilderExtensions.cs @@ -2,8 +2,8 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using JetBrains.Annotations; +using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Metadata.Builders; -using Microsoft.EntityFrameworkCore.Metadata.Internal; using Microsoft.EntityFrameworkCore.Utilities; // ReSharper disable once CheckNamespace diff --git a/src/EFCore.Relational/Extensions/RelationalIndexExtensions.cs b/src/EFCore.Relational/Extensions/RelationalIndexExtensions.cs index 37f32e624e5..2bf55a8c032 100644 --- a/src/EFCore.Relational/Extensions/RelationalIndexExtensions.cs +++ b/src/EFCore.Relational/Extensions/RelationalIndexExtensions.cs @@ -6,7 +6,6 @@ using JetBrains.Annotations; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Metadata; -using Microsoft.EntityFrameworkCore.Metadata.Internal; using Microsoft.EntityFrameworkCore.Utilities; // ReSharper disable once CheckNamespace diff --git a/src/EFCore.Relational/Extensions/RelationalKeyBuilderExtensions.cs b/src/EFCore.Relational/Extensions/RelationalKeyBuilderExtensions.cs index bc6ccfd2029..c7ee6eead7e 100644 --- a/src/EFCore.Relational/Extensions/RelationalKeyBuilderExtensions.cs +++ b/src/EFCore.Relational/Extensions/RelationalKeyBuilderExtensions.cs @@ -2,8 +2,8 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using JetBrains.Annotations; +using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Metadata.Builders; -using Microsoft.EntityFrameworkCore.Metadata.Internal; using Microsoft.EntityFrameworkCore.Utilities; // ReSharper disable once CheckNamespace diff --git a/src/EFCore.Relational/Extensions/RelationalPropertyBuilderExtensions.cs b/src/EFCore.Relational/Extensions/RelationalPropertyBuilderExtensions.cs index 828f6524708..c7bf99d0ab8 100644 --- a/src/EFCore.Relational/Extensions/RelationalPropertyBuilderExtensions.cs +++ b/src/EFCore.Relational/Extensions/RelationalPropertyBuilderExtensions.cs @@ -3,8 +3,8 @@ using System; using JetBrains.Annotations; +using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Metadata.Builders; -using Microsoft.EntityFrameworkCore.Metadata.Internal; using Microsoft.EntityFrameworkCore.Utilities; // ReSharper disable once CheckNamespace diff --git a/src/EFCore.Relational/Infrastructure/RelationalModelCustomizer.cs b/src/EFCore.Relational/Infrastructure/RelationalModelCustomizer.cs index ded64a992b5..725bc7b67fc 100644 --- a/src/EFCore.Relational/Infrastructure/RelationalModelCustomizer.cs +++ b/src/EFCore.Relational/Infrastructure/RelationalModelCustomizer.cs @@ -1,6 +1,7 @@ // 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.Linq; using System.Reflection; using JetBrains.Annotations; @@ -100,12 +101,12 @@ protected virtual void FindDbFunctions([NotNull] ModelBuilder modelBuilder, [Not /// Adds the entity types found in properties on the context to the model. /// /// The being used to build the model. - /// The context to find properties on. - protected override void FindSets(ModelBuilder modelBuilder, DbContext context) + /// The context type to find properties on. + protected override void FindSets(ModelBuilder modelBuilder, Type contextType) { - base.FindSets(modelBuilder, context); + base.FindSets(modelBuilder, contextType); - var sets = Dependencies.SetFinder.CreateClrTypeDbSetMapping(context); + var sets = Dependencies.SetFinder.CreateClrTypeDbSetMapping(contextType); foreach (var entityType in modelBuilder.Model.GetEntityTypes().Cast()) { diff --git a/src/EFCore.Relational/Internal/RelationalPropertyExtensions.cs b/src/EFCore.Relational/Internal/RelationalPropertyExtensions.cs index 0c3abcb5508..5a9bfaa9a85 100644 --- a/src/EFCore.Relational/Internal/RelationalPropertyExtensions.cs +++ b/src/EFCore.Relational/Internal/RelationalPropertyExtensions.cs @@ -6,7 +6,6 @@ using System.Linq; using JetBrains.Annotations; using Microsoft.EntityFrameworkCore.Metadata; -using Microsoft.EntityFrameworkCore.Metadata.Internal; using Microsoft.EntityFrameworkCore.Storage; namespace Microsoft.EntityFrameworkCore.Internal diff --git a/src/EFCore.Relational/Metadata/Conventions/Infrastructure/RelationalConventionSetBuilder.cs b/src/EFCore.Relational/Metadata/Conventions/Infrastructure/RelationalConventionSetBuilder.cs index 8c50904d7c2..cee3ec2951a 100644 --- a/src/EFCore.Relational/Metadata/Conventions/Infrastructure/RelationalConventionSetBuilder.cs +++ b/src/EFCore.Relational/Metadata/Conventions/Infrastructure/RelationalConventionSetBuilder.cs @@ -2,7 +2,6 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using JetBrains.Annotations; -using Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal; using Microsoft.EntityFrameworkCore.Utilities; using Microsoft.Extensions.DependencyInjection; @@ -60,32 +59,35 @@ public override ConventionSet CreateConventionSet() { var conventionSet = base.CreateConventionSet(); - var logger = Dependencies.Logger; - - ValueGeneratorConvention valueGeneratorConvention = new RelationalValueGeneratorConvention(logger); + ValueGeneratorConvention valueGeneratorConvention = new RelationalValueGeneratorConvention(Dependencies, RelationalDependencies); ReplaceConvention(conventionSet.EntityTypeBaseTypeChangedConventions, valueGeneratorConvention); ReplaceConvention(conventionSet.EntityTypePrimaryKeyChangedConventions, valueGeneratorConvention); ReplaceConvention(conventionSet.ForeignKeyAddedConventions, valueGeneratorConvention); ReplaceConvention(conventionSet.ForeignKeyRemovedConventions, valueGeneratorConvention); - var relationalColumnAttributeConvention = new RelationalColumnAttributeConvention(logger); + var relationalColumnAttributeConvention = new RelationalColumnAttributeConvention(Dependencies, RelationalDependencies); conventionSet.PropertyAddedConventions.Add(relationalColumnAttributeConvention); - var storeGenerationConvention = new StoreGenerationConvention(); - conventionSet.EntityTypeAddedConventions.Add(new RelationalTableAttributeConvention(logger)); - conventionSet.EntityTypeBaseTypeChangedConventions.Add( - new TableNameFromDbSetConvention(Dependencies.Context?.Context, Dependencies.SetFinder, logger)); + var storeGenerationConvention = new StoreGenerationConvention(Dependencies, RelationalDependencies); + conventionSet.EntityTypeAddedConventions.Add(new RelationalTableAttributeConvention(Dependencies, RelationalDependencies)); + conventionSet.EntityTypeBaseTypeChangedConventions.Add(new TableNameFromDbSetConvention(Dependencies, RelationalDependencies)); conventionSet.PropertyFieldChangedConventions.Add(relationalColumnAttributeConvention); conventionSet.PropertyAnnotationChangedConventions.Add(storeGenerationConvention); conventionSet.PropertyAnnotationChangedConventions.Add((RelationalValueGeneratorConvention)valueGeneratorConvention); - var sharedTableConvention = new SharedTableConvention(logger); - conventionSet.ModelFinalizedConventions.Add(storeGenerationConvention); - conventionSet.ModelFinalizedConventions.Add(sharedTableConvention); + var sharedTableConvention = new SharedTableConvention(Dependencies, RelationalDependencies); + ConventionSet.AddBefore( + conventionSet.ModelFinalizedConventions, + storeGenerationConvention, + typeof(ValidatingConvention)); + ConventionSet.AddBefore( + conventionSet.ModelFinalizedConventions, + sharedTableConvention, + typeof(ValidatingConvention)); - conventionSet.ModelAnnotationChangedConventions.Add(new RelationalDbFunctionConvention(logger)); + conventionSet.ModelAnnotationChangedConventions.Add(new RelationalDbFunctionConvention(Dependencies, RelationalDependencies)); return conventionSet; } diff --git a/src/EFCore.Relational/Metadata/Conventions/Infrastructure/RelationalConventionSetBuilderDependencies.cs b/src/EFCore.Relational/Metadata/Conventions/Infrastructure/RelationalConventionSetBuilderDependencies.cs index 58a03cb0db6..e32a567074c 100644 --- a/src/EFCore.Relational/Metadata/Conventions/Infrastructure/RelationalConventionSetBuilderDependencies.cs +++ b/src/EFCore.Relational/Metadata/Conventions/Infrastructure/RelationalConventionSetBuilderDependencies.cs @@ -1,9 +1,6 @@ // 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 JetBrains.Annotations; -using Microsoft.EntityFrameworkCore.Storage; -using Microsoft.EntityFrameworkCore.Utilities; using Microsoft.Extensions.DependencyInjection; namespace Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure @@ -52,26 +49,8 @@ public sealed class RelationalConventionSetBuilderDependencies /// The implementation does not need to be thread-safe. /// /// - /// The type mapping source. - public RelationalConventionSetBuilderDependencies( - [NotNull] IRelationalTypeMappingSource typeMappingSource) + public RelationalConventionSetBuilderDependencies() { - Check.NotNull(typeMappingSource, nameof(typeMappingSource)); - - TypeMappingSource = typeMappingSource; } - - /// - /// The type mapping source. - /// - public IRelationalTypeMappingSource TypeMappingSource { get; } - - /// - /// Clones this dependency parameter object with one service replaced. - /// - /// A replacement for the current dependency of this type. - /// A new parameter object with the given service replaced. - public RelationalConventionSetBuilderDependencies With([NotNull] IRelationalTypeMappingSource typeMappingSource) - => new RelationalConventionSetBuilderDependencies(typeMappingSource); } } diff --git a/src/EFCore.Relational/Metadata/Conventions/Internal/RelationalColumnAttributeConvention.cs b/src/EFCore.Relational/Metadata/Conventions/RelationalColumnAttributeConvention.cs similarity index 86% rename from src/EFCore.Relational/Metadata/Conventions/Internal/RelationalColumnAttributeConvention.cs rename to src/EFCore.Relational/Metadata/Conventions/RelationalColumnAttributeConvention.cs index 46296e58e04..ee24bbe5339 100644 --- a/src/EFCore.Relational/Metadata/Conventions/Internal/RelationalColumnAttributeConvention.cs +++ b/src/EFCore.Relational/Metadata/Conventions/RelationalColumnAttributeConvention.cs @@ -4,10 +4,10 @@ using System.ComponentModel.DataAnnotations.Schema; using System.Reflection; using JetBrains.Annotations; -using Microsoft.EntityFrameworkCore.Diagnostics; using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure; -namespace Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal +namespace Microsoft.EntityFrameworkCore.Metadata.Conventions { /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -23,8 +23,10 @@ public class RelationalColumnAttributeConvention : PropertyAttributeConvention - public RelationalColumnAttributeConvention([NotNull] IDiagnosticsLogger logger) - : base(logger) + public RelationalColumnAttributeConvention( + [NotNull] ProviderConventionSetBuilderDependencies dependencies, + [NotNull] RelationalConventionSetBuilderDependencies relationalDependencies) + : base(dependencies) { } diff --git a/src/EFCore.Relational/Metadata/Conventions/Internal/RelationalDbFunctionConvention.cs b/src/EFCore.Relational/Metadata/Conventions/RelationalDbFunctionConvention.cs similarity index 80% rename from src/EFCore.Relational/Metadata/Conventions/Internal/RelationalDbFunctionConvention.cs rename to src/EFCore.Relational/Metadata/Conventions/RelationalDbFunctionConvention.cs index e4f746011a1..fa1551ca3cb 100644 --- a/src/EFCore.Relational/Metadata/Conventions/Internal/RelationalDbFunctionConvention.cs +++ b/src/EFCore.Relational/Metadata/Conventions/RelationalDbFunctionConvention.cs @@ -5,12 +5,11 @@ using System.Linq; using System.Reflection; using JetBrains.Annotations; -using Microsoft.EntityFrameworkCore.Diagnostics; using Microsoft.EntityFrameworkCore.Metadata.Builders; -using Microsoft.EntityFrameworkCore.Metadata.Internal; +using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure; using Microsoft.EntityFrameworkCore.Utilities; -namespace Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal +namespace Microsoft.EntityFrameworkCore.Metadata.Conventions { /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -26,18 +25,17 @@ public class RelationalDbFunctionConvention : IModelAnnotationChangedConvention /// 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 RelationalDbFunctionConvention([NotNull] IDiagnosticsLogger logger) + public RelationalDbFunctionConvention( + [NotNull] ProviderConventionSetBuilderDependencies dependencies, + [NotNull] RelationalConventionSetBuilderDependencies relationalDependencies) { - Logger = logger; + Dependencies = dependencies; } /// - /// 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. + /// Parameter object containing service dependencies. /// - protected virtual IDiagnosticsLogger Logger { get; } + protected virtual ProviderConventionSetBuilderDependencies Dependencies { get; } /// /// Called after an annotation is changed on an model. diff --git a/src/EFCore.Relational/Metadata/Conventions/Internal/RelationalMaxIdentifierLengthConvention.cs b/src/EFCore.Relational/Metadata/Conventions/RelationalMaxIdentifierLengthConvention.cs similarity index 75% rename from src/EFCore.Relational/Metadata/Conventions/Internal/RelationalMaxIdentifierLengthConvention.cs rename to src/EFCore.Relational/Metadata/Conventions/RelationalMaxIdentifierLengthConvention.cs index fb42c335c45..3f0285cf64c 100644 --- a/src/EFCore.Relational/Metadata/Conventions/Internal/RelationalMaxIdentifierLengthConvention.cs +++ b/src/EFCore.Relational/Metadata/Conventions/RelationalMaxIdentifierLengthConvention.cs @@ -2,10 +2,10 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using JetBrains.Annotations; -using Microsoft.EntityFrameworkCore.Diagnostics; using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure; -namespace Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal +namespace Microsoft.EntityFrameworkCore.Metadata.Conventions { /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -21,19 +21,19 @@ public class RelationalMaxIdentifierLengthConvention : IModelInitializedConventi /// 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 RelationalMaxIdentifierLengthConvention(int maxIdentifierLength, [NotNull] IDiagnosticsLogger logger) + public RelationalMaxIdentifierLengthConvention( + int maxIdentifierLength, + [NotNull] ProviderConventionSetBuilderDependencies dependencies, + [NotNull] RelationalConventionSetBuilderDependencies relationalDependencies) { MaxIdentifierLength = maxIdentifierLength; - Logger = logger; + Dependencies = dependencies; } /// - /// 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. + /// Parameter object containing service dependencies. /// - protected virtual IDiagnosticsLogger Logger { get; } + protected virtual ProviderConventionSetBuilderDependencies Dependencies { get; } /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.Relational/Metadata/Conventions/Internal/RelationalTableAttributeConvention.cs b/src/EFCore.Relational/Metadata/Conventions/RelationalTableAttributeConvention.cs similarity index 86% rename from src/EFCore.Relational/Metadata/Conventions/Internal/RelationalTableAttributeConvention.cs rename to src/EFCore.Relational/Metadata/Conventions/RelationalTableAttributeConvention.cs index e0f6416d388..5935dc737ee 100644 --- a/src/EFCore.Relational/Metadata/Conventions/Internal/RelationalTableAttributeConvention.cs +++ b/src/EFCore.Relational/Metadata/Conventions/RelationalTableAttributeConvention.cs @@ -3,10 +3,10 @@ using System.ComponentModel.DataAnnotations.Schema; using JetBrains.Annotations; -using Microsoft.EntityFrameworkCore.Diagnostics; using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure; -namespace Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal +namespace Microsoft.EntityFrameworkCore.Metadata.Conventions { /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -22,8 +22,10 @@ public class RelationalTableAttributeConvention : EntityTypeAttributeConvention< /// 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 RelationalTableAttributeConvention([NotNull] IDiagnosticsLogger logger) - : base(logger) + public RelationalTableAttributeConvention( + [NotNull] ProviderConventionSetBuilderDependencies dependencies, + [NotNull] RelationalConventionSetBuilderDependencies relationalDependencies) + : base(dependencies) { } diff --git a/src/EFCore.Relational/Metadata/Conventions/Internal/RelationalValueGeneratorConvention.cs b/src/EFCore.Relational/Metadata/Conventions/RelationalValueGeneratorConvention.cs similarity index 76% rename from src/EFCore.Relational/Metadata/Conventions/Internal/RelationalValueGeneratorConvention.cs rename to src/EFCore.Relational/Metadata/Conventions/RelationalValueGeneratorConvention.cs index 72b52f1270d..e6af9bbdb0e 100644 --- a/src/EFCore.Relational/Metadata/Conventions/Internal/RelationalValueGeneratorConvention.cs +++ b/src/EFCore.Relational/Metadata/Conventions/RelationalValueGeneratorConvention.cs @@ -2,11 +2,10 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using JetBrains.Annotations; -using Microsoft.EntityFrameworkCore.Diagnostics; using Microsoft.EntityFrameworkCore.Metadata.Builders; -using Microsoft.EntityFrameworkCore.Metadata.Internal; +using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure; -namespace Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal +namespace Microsoft.EntityFrameworkCore.Metadata.Conventions { /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -22,8 +21,10 @@ public class RelationalValueGeneratorConvention : ValueGeneratorConvention, IPro /// 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 RelationalValueGeneratorConvention([NotNull] IDiagnosticsLogger logger) - : base(logger) + public RelationalValueGeneratorConvention( + [NotNull] ProviderConventionSetBuilderDependencies dependencies, + [NotNull] RelationalConventionSetBuilderDependencies relationalDependencies) + : base(dependencies) { } @@ -58,9 +59,17 @@ public virtual void ProcessPropertyAnnotationChanged( /// /// The property. /// The store value generation strategy to set for the given property. - public override ValueGenerated? GetValueGenerated(IConventionProperty property) + protected override ValueGenerated? GetValueGenerated(IConventionProperty property) + => GetValueGenerated((IProperty)property); + + /// + /// Returns the store value generation strategy to set for the given property. + /// + /// The property. + /// The store value generation strategy to set for the given property. + public static new ValueGenerated? GetValueGenerated([NotNull] IProperty property) { - var valueGenerated = base.GetValueGenerated(property); + var valueGenerated = ValueGeneratorConvention.GetValueGenerated(property); if (valueGenerated != null) { return valueGenerated; diff --git a/src/EFCore.Relational/Metadata/Conventions/Internal/SharedTableConvention.cs b/src/EFCore.Relational/Metadata/Conventions/SharedTableConvention.cs similarity index 95% rename from src/EFCore.Relational/Metadata/Conventions/Internal/SharedTableConvention.cs rename to src/EFCore.Relational/Metadata/Conventions/SharedTableConvention.cs index 9e48b3a11cb..2c20b39e8c4 100644 --- a/src/EFCore.Relational/Metadata/Conventions/Internal/SharedTableConvention.cs +++ b/src/EFCore.Relational/Metadata/Conventions/SharedTableConvention.cs @@ -6,12 +6,12 @@ using System.Linq; using System.Reflection; using JetBrains.Annotations; -using Microsoft.EntityFrameworkCore.Diagnostics; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure; using Microsoft.EntityFrameworkCore.Metadata.Internal; -namespace Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal +namespace Microsoft.EntityFrameworkCore.Metadata.Conventions { /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -27,18 +27,17 @@ public class SharedTableConvention : IModelFinalizedConvention /// 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 SharedTableConvention([NotNull] IDiagnosticsLogger logger) + public SharedTableConvention( + [NotNull] ProviderConventionSetBuilderDependencies dependencies, + [NotNull] RelationalConventionSetBuilderDependencies relationalDependencies) { - Logger = logger; + Dependencies = dependencies; } /// - /// 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. + /// Parameter object containing service dependencies. /// - protected virtual IDiagnosticsLogger Logger { get; } + protected virtual ProviderConventionSetBuilderDependencies Dependencies { get; } /// /// Called after a model is finalized. diff --git a/src/EFCore.Relational/Metadata/Conventions/Internal/StoreGenerationConvention.cs b/src/EFCore.Relational/Metadata/Conventions/StoreGenerationConvention.cs similarity index 81% rename from src/EFCore.Relational/Metadata/Conventions/Internal/StoreGenerationConvention.cs rename to src/EFCore.Relational/Metadata/Conventions/StoreGenerationConvention.cs index bdc1669eadb..d45e7ca81d4 100644 --- a/src/EFCore.Relational/Metadata/Conventions/Internal/StoreGenerationConvention.cs +++ b/src/EFCore.Relational/Metadata/Conventions/StoreGenerationConvention.cs @@ -2,11 +2,12 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; +using JetBrains.Annotations; using Microsoft.EntityFrameworkCore.Diagnostics; using Microsoft.EntityFrameworkCore.Metadata.Builders; -using Microsoft.EntityFrameworkCore.Metadata.Internal; +using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure; -namespace Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal +namespace Microsoft.EntityFrameworkCore.Metadata.Conventions { /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -16,6 +17,24 @@ namespace Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal /// public class StoreGenerationConvention : IPropertyAnnotationChangedConvention, IModelFinalizedConvention { + /// + /// 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 StoreGenerationConvention( + [NotNull] ProviderConventionSetBuilderDependencies dependencies, + [NotNull] RelationalConventionSetBuilderDependencies relationalDependencies) + { + Dependencies = dependencies; + } + + /// + /// Parameter object containing service dependencies. + /// + protected virtual ProviderConventionSetBuilderDependencies Dependencies { get; } + /// /// Called after an annotation is changed on a property. /// @@ -91,7 +110,7 @@ public virtual void ProcessModelFinalized(IConventionModelBuilder modelBuilder, /// Throws if there is conflicting store generation configuration for this property. /// /// The property to check. - protected virtual void Validate(IConventionProperty property) + protected virtual void Validate([NotNull] IConventionProperty property) { if (property.GetDefaultValue() != null) { diff --git a/src/EFCore.Relational/Metadata/Conventions/Internal/TableNameFromDbSetConvention.cs b/src/EFCore.Relational/Metadata/Conventions/TableNameFromDbSetConvention.cs similarity index 73% rename from src/EFCore.Relational/Metadata/Conventions/Internal/TableNameFromDbSetConvention.cs rename to src/EFCore.Relational/Metadata/Conventions/TableNameFromDbSetConvention.cs index b386db4ff70..8d5bef19fde 100644 --- a/src/EFCore.Relational/Metadata/Conventions/Internal/TableNameFromDbSetConvention.cs +++ b/src/EFCore.Relational/Metadata/Conventions/TableNameFromDbSetConvention.cs @@ -4,11 +4,11 @@ using System; using System.Collections.Generic; using JetBrains.Annotations; -using Microsoft.EntityFrameworkCore.Diagnostics; using Microsoft.EntityFrameworkCore.Internal; using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure; -namespace Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal +namespace Microsoft.EntityFrameworkCore.Metadata.Conventions { /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -27,25 +27,18 @@ public class TableNameFromDbSetConvention : IEntityTypeBaseTypeChangedConvention /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public TableNameFromDbSetConvention( - [CanBeNull] DbContext context, - [CanBeNull] IDbSetFinder setFinder, - [NotNull] IDiagnosticsLogger logger) + [NotNull] ProviderConventionSetBuilderDependencies dependencies, + [NotNull] RelationalConventionSetBuilderDependencies relationalDependencies) { - _sets = context != null - && setFinder != null - ? setFinder.CreateClrTypeDbSetMapping(context) - : new Dictionary(); + _sets = dependencies.SetFinder.CreateClrTypeDbSetMapping(dependencies.ContextType); - Logger = logger; + Dependencies = dependencies; } /// - /// 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. + /// Parameter object containing service dependencies. /// - protected virtual IDiagnosticsLogger Logger { get; } + protected virtual ProviderConventionSetBuilderDependencies Dependencies { get; } /// /// Called after the base type of an entity type changes. diff --git a/src/EFCore.Relational/Metadata/Internal/RelationalAnnotationNames.cs b/src/EFCore.Relational/Metadata/Internal/RelationalAnnotationNames.cs deleted file mode 100644 index 02ae30f9319..00000000000 --- a/src/EFCore.Relational/Metadata/Internal/RelationalAnnotationNames.cs +++ /dev/null @@ -1,142 +0,0 @@ -// 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. - -namespace Microsoft.EntityFrameworkCore.Metadata.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 static class RelationalAnnotationNames - { - /// - /// 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 const string Prefix = "Relational:"; - - /// - /// 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 const string ColumnName = Prefix + "ColumnName"; - - /// - /// 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 const string ColumnType = Prefix + "ColumnType"; - - /// - /// 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 const string DefaultValueSql = Prefix + "DefaultValueSql"; - - /// - /// 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 const string ComputedColumnSql = Prefix + "ComputedColumnSql"; - - /// - /// 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 const string DefaultValue = Prefix + "DefaultValue"; - - /// - /// 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 const string TableName = Prefix + "TableName"; - - /// - /// 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 const string Schema = Prefix + "Schema"; - - /// - /// 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 const string DefaultSchema = Prefix + "DefaultSchema"; - - /// - /// 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 const string Name = Prefix + "Name"; - - /// - /// 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 const string SequencePrefix = Prefix + "Sequence:"; - - /// - /// 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 const string CheckConstraints = Prefix + "CheckConstraints"; - - /// - /// 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 const string Filter = Prefix + "Filter"; - - /// - /// 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 const string DbFunction = Prefix + "DbFunction"; - - /// - /// 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 const string MaxIdentifierLength = Prefix + "MaxIdentifierLength"; - - /// - /// 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 const string IsFixedLength = Prefix + "IsFixedLength"; - } -} diff --git a/src/EFCore.Relational/Metadata/RelationalAnnotationNames.cs b/src/EFCore.Relational/Metadata/RelationalAnnotationNames.cs new file mode 100644 index 00000000000..8e8f4a17e8a --- /dev/null +++ b/src/EFCore.Relational/Metadata/RelationalAnnotationNames.cs @@ -0,0 +1,92 @@ +// 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. + +namespace Microsoft.EntityFrameworkCore.Metadata +{ + /// + /// Names for well-known relational model annotations. Applications should not use these names + /// directly, but should instead use the extension methods on metadata objects. + /// + public static class RelationalAnnotationNames + { + /// + /// The prefix used for any relational annotation. + /// + public const string Prefix = "Relational:"; + + /// + /// The name for column name annotations. + /// + public const string ColumnName = Prefix + "ColumnName"; + + /// + /// The name for column type annotations. + /// + public const string ColumnType = Prefix + "ColumnType"; + + /// + /// The name for default value SQL expression annotations. + /// + public const string DefaultValueSql = Prefix + "DefaultValueSql"; + + /// + /// The name for computed value SQL expression annotations. + /// + public const string ComputedColumnSql = Prefix + "ComputedColumnSql"; + + /// + /// The name for default value annotations. + /// + public const string DefaultValue = Prefix + "DefaultValue"; + + /// + /// The name for table name annotations. + /// + public const string TableName = Prefix + "TableName"; + + /// + /// The name for schema name annotations. + /// + public const string Schema = Prefix + "Schema"; + + /// + /// The name for default schema annotations. + /// + public const string DefaultSchema = Prefix + "DefaultSchema"; + + /// + /// The name for constraint name annotations. + /// + public const string Name = Prefix + "Name"; + + /// + /// The prefix for serialized sequence annotations. + /// + public const string SequencePrefix = Prefix + "Sequence:"; + + /// + /// The name for check constraint annotations. + /// + public const string CheckConstraints = Prefix + "CheckConstraints"; + + /// + /// The name for filter annotations. + /// + public const string Filter = Prefix + "Filter"; + + /// + /// The name for DbFunction annotations. + /// + public const string DbFunction = Prefix + "DbFunction"; + + /// + /// The maximum length for database identifiers. + /// + public const string MaxIdentifierLength = Prefix + "MaxIdentifierLength"; + + /// + /// A flag indicating whether the property is constrained to fixed length values. + /// + public const string IsFixedLength = Prefix + "IsFixedLength"; + } +} diff --git a/src/EFCore.SqlServer/Design/Internal/SqlServerAnnotationCodeGenerator.cs b/src/EFCore.SqlServer/Design/Internal/SqlServerAnnotationCodeGenerator.cs index d26b2a3c009..6d955d9354c 100644 --- a/src/EFCore.SqlServer/Design/Internal/SqlServerAnnotationCodeGenerator.cs +++ b/src/EFCore.SqlServer/Design/Internal/SqlServerAnnotationCodeGenerator.cs @@ -5,7 +5,6 @@ using Microsoft.EntityFrameworkCore.Design; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Metadata; -using Microsoft.EntityFrameworkCore.Metadata.Internal; using Microsoft.EntityFrameworkCore.SqlServer.Metadata.Internal; using Microsoft.EntityFrameworkCore.Utilities; diff --git a/src/EFCore.SqlServer/Metadata/Conventions/SqlServerConventionSetBuilder.cs b/src/EFCore.SqlServer/Metadata/Conventions/SqlServerConventionSetBuilder.cs index c163d68fec5..c6bcbd62b4d 100644 --- a/src/EFCore.SqlServer/Metadata/Conventions/SqlServerConventionSetBuilder.cs +++ b/src/EFCore.SqlServer/Metadata/Conventions/SqlServerConventionSetBuilder.cs @@ -3,11 +3,10 @@ using JetBrains.Annotations; using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure; -using Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal; -using Microsoft.EntityFrameworkCore.SqlServer.Metadata.Conventions.Internal; using Microsoft.EntityFrameworkCore.Storage; using Microsoft.Extensions.DependencyInjection; +// ReSharper disable once CheckNamespace namespace Microsoft.EntityFrameworkCore.Metadata.Conventions { /// @@ -49,16 +48,15 @@ public override ConventionSet CreateConventionSet() { var conventionSet = base.CreateConventionSet(); - var logger = Dependencies.Logger; - - var valueGenerationStrategyConvention = new SqlServerValueGenerationStrategyConvention(logger); + var valueGenerationStrategyConvention = new SqlServerValueGenerationStrategyConvention(Dependencies); conventionSet.ModelInitializedConventions.Add(valueGenerationStrategyConvention); - conventionSet.ModelInitializedConventions.Add(new RelationalMaxIdentifierLengthConvention(128, logger)); + conventionSet.ModelInitializedConventions.Add( + new RelationalMaxIdentifierLengthConvention(128, Dependencies, RelationalDependencies)); - ValueGeneratorConvention valueGeneratorConvention = new SqlServerValueGeneratorConvention(logger); + ValueGeneratorConvention valueGeneratorConvention = new SqlServerValueGeneratorConvention(Dependencies, RelationalDependencies); ReplaceConvention(conventionSet.EntityTypeBaseTypeChangedConventions, valueGeneratorConvention); - var sqlServerInMemoryTablesConvention = new SqlServerMemoryOptimizedTablesConvention(logger); + var sqlServerInMemoryTablesConvention = new SqlServerMemoryOptimizedTablesConvention(Dependencies); conventionSet.EntityTypeAnnotationChangedConventions.Add(sqlServerInMemoryTablesConvention); ReplaceConvention(conventionSet.EntityTypePrimaryKeyChangedConventions, valueGeneratorConvention); @@ -69,11 +67,14 @@ public override ConventionSet CreateConventionSet() ReplaceConvention(conventionSet.ForeignKeyRemovedConventions, valueGeneratorConvention); - var sqlServerIndexConvention = new SqlServerIndexConvention(_sqlGenerationHelper, logger); + var sqlServerIndexConvention = new SqlServerIndexConvention(Dependencies, _sqlGenerationHelper); conventionSet.EntityTypeBaseTypeChangedConventions.Add(sqlServerIndexConvention); - conventionSet.ModelFinalizedConventions.Add(valueGenerationStrategyConvention); + ConventionSet.AddBefore( + conventionSet.ModelFinalizedConventions, + valueGenerationStrategyConvention, + typeof(ValidatingConvention)); conventionSet.IndexAddedConventions.Add(sqlServerInMemoryTablesConvention); conventionSet.IndexAddedConventions.Add(sqlServerIndexConvention); @@ -84,14 +85,16 @@ public override ConventionSet CreateConventionSet() conventionSet.PropertyNullabilityChangedConventions.Add(sqlServerIndexConvention); - StoreGenerationConvention storeGenerationConvention = new SqlServerStoreGenerationConvention(); + StoreGenerationConvention storeGenerationConvention = + new SqlServerStoreGenerationConvention(Dependencies, RelationalDependencies); conventionSet.PropertyAnnotationChangedConventions.Add(sqlServerIndexConvention); ReplaceConvention(conventionSet.PropertyAnnotationChangedConventions, storeGenerationConvention); ReplaceConvention( conventionSet.PropertyAnnotationChangedConventions, (RelationalValueGeneratorConvention)valueGeneratorConvention); ReplaceConvention( - conventionSet.ModelAnnotationChangedConventions, (RelationalDbFunctionConvention)new SqlServerDbFunctionConvention(logger)); + conventionSet.ModelAnnotationChangedConventions, + (RelationalDbFunctionConvention)new SqlServerDbFunctionConvention(Dependencies, RelationalDependencies)); ReplaceConvention(conventionSet.ModelFinalizedConventions, storeGenerationConvention); diff --git a/src/EFCore.SqlServer/Metadata/Conventions/Internal/SqlServerDbFunctionConvention.cs b/src/EFCore.SqlServer/Metadata/Conventions/SqlServerDbFunctionConvention.cs similarity index 80% rename from src/EFCore.SqlServer/Metadata/Conventions/Internal/SqlServerDbFunctionConvention.cs rename to src/EFCore.SqlServer/Metadata/Conventions/SqlServerDbFunctionConvention.cs index 8d5d42eae17..a1c8df3cbc9 100644 --- a/src/EFCore.SqlServer/Metadata/Conventions/Internal/SqlServerDbFunctionConvention.cs +++ b/src/EFCore.SqlServer/Metadata/Conventions/SqlServerDbFunctionConvention.cs @@ -2,15 +2,12 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using JetBrains.Annotations; -using Microsoft.EntityFrameworkCore.Diagnostics; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Metadata.Builders; -using Microsoft.EntityFrameworkCore.Metadata.Conventions; -using Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal; +using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure; using Microsoft.EntityFrameworkCore.Metadata.Internal; -namespace Microsoft.EntityFrameworkCore.SqlServer.Metadata.Conventions.Internal +// ReSharper disable once CheckNamespace +namespace Microsoft.EntityFrameworkCore.Metadata.Conventions { /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -26,8 +23,10 @@ public class SqlServerDbFunctionConvention : RelationalDbFunctionConvention /// 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 SqlServerDbFunctionConvention([NotNull] IDiagnosticsLogger logger) - : base(logger) + public SqlServerDbFunctionConvention( + [NotNull] ProviderConventionSetBuilderDependencies dependencies, + [NotNull] RelationalConventionSetBuilderDependencies relationalDependencies) + : base(dependencies, relationalDependencies) { } diff --git a/src/EFCore.SqlServer/Metadata/Conventions/Internal/SqlServerIndexConvention.cs b/src/EFCore.SqlServer/Metadata/Conventions/SqlServerIndexConvention.cs similarity index 89% rename from src/EFCore.SqlServer/Metadata/Conventions/Internal/SqlServerIndexConvention.cs rename to src/EFCore.SqlServer/Metadata/Conventions/SqlServerIndexConvention.cs index 43504ddb0ee..6c3f5bdd9db 100644 --- a/src/EFCore.SqlServer/Metadata/Conventions/Internal/SqlServerIndexConvention.cs +++ b/src/EFCore.SqlServer/Metadata/Conventions/SqlServerIndexConvention.cs @@ -4,15 +4,13 @@ using System.Linq; using System.Text; using JetBrains.Annotations; -using Microsoft.EntityFrameworkCore.Diagnostics; -using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Metadata.Builders; -using Microsoft.EntityFrameworkCore.Metadata.Conventions; -using Microsoft.EntityFrameworkCore.Metadata.Internal; +using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure; using Microsoft.EntityFrameworkCore.SqlServer.Metadata.Internal; using Microsoft.EntityFrameworkCore.Storage; -namespace Microsoft.EntityFrameworkCore.SqlServer.Metadata.Conventions.Internal +// ReSharper disable once CheckNamespace +namespace Microsoft.EntityFrameworkCore.Metadata.Conventions { /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -37,20 +35,16 @@ public class SqlServerIndexConvention : /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public SqlServerIndexConvention( - [NotNull] ISqlGenerationHelper sqlGenerationHelper, - [NotNull] IDiagnosticsLogger logger) + [NotNull] ProviderConventionSetBuilderDependencies dependencies, [NotNull] ISqlGenerationHelper sqlGenerationHelper) { _sqlGenerationHelper = sqlGenerationHelper; - Logger = logger; + Dependencies = dependencies; } /// - /// 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. + /// Parameter object containing service dependencies. /// - protected virtual IDiagnosticsLogger Logger { get; } + protected virtual ProviderConventionSetBuilderDependencies Dependencies { get; } /// /// Called after the base type of an entity type changes. diff --git a/src/EFCore.SqlServer/Metadata/Conventions/Internal/SqlServerMemoryOptimizedTablesConvention.cs b/src/EFCore.SqlServer/Metadata/Conventions/SqlServerMemoryOptimizedTablesConvention.cs similarity index 81% rename from src/EFCore.SqlServer/Metadata/Conventions/Internal/SqlServerMemoryOptimizedTablesConvention.cs rename to src/EFCore.SqlServer/Metadata/Conventions/SqlServerMemoryOptimizedTablesConvention.cs index 88321b6b1cb..8eef7ed1821 100644 --- a/src/EFCore.SqlServer/Metadata/Conventions/Internal/SqlServerMemoryOptimizedTablesConvention.cs +++ b/src/EFCore.SqlServer/Metadata/Conventions/SqlServerMemoryOptimizedTablesConvention.cs @@ -3,13 +3,12 @@ using System.Linq; using JetBrains.Annotations; -using Microsoft.EntityFrameworkCore.Diagnostics; -using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Metadata.Builders; -using Microsoft.EntityFrameworkCore.Metadata.Conventions; +using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure; using Microsoft.EntityFrameworkCore.SqlServer.Metadata.Internal; -namespace Microsoft.EntityFrameworkCore.SqlServer.Metadata.Conventions.Internal +// ReSharper disable once CheckNamespace +namespace Microsoft.EntityFrameworkCore.Metadata.Conventions { /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -17,7 +16,9 @@ namespace Microsoft.EntityFrameworkCore.SqlServer.Metadata.Conventions.Internal /// 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 class SqlServerMemoryOptimizedTablesConvention : IEntityTypeAnnotationChangedConvention, IKeyAddedConvention, + public class SqlServerMemoryOptimizedTablesConvention : + IEntityTypeAnnotationChangedConvention, + IKeyAddedConvention, IIndexAddedConvention { /// @@ -26,18 +27,15 @@ public class SqlServerMemoryOptimizedTablesConvention : IEntityTypeAnnotationCha /// 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 SqlServerMemoryOptimizedTablesConvention([NotNull] IDiagnosticsLogger logger) + public SqlServerMemoryOptimizedTablesConvention([NotNull] ProviderConventionSetBuilderDependencies dependencies) { - Logger = logger; + Dependencies = dependencies; } /// - /// 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. + /// Parameter object containing service dependencies. /// - protected virtual IDiagnosticsLogger Logger { get; } + protected virtual ProviderConventionSetBuilderDependencies Dependencies { get; } /// /// Called after an annotation is changed on an entity type. diff --git a/src/EFCore.SqlServer/Metadata/Conventions/Internal/SqlServerStoreGenerationConvention.cs b/src/EFCore.SqlServer/Metadata/Conventions/SqlServerStoreGenerationConvention.cs similarity index 77% rename from src/EFCore.SqlServer/Metadata/Conventions/Internal/SqlServerStoreGenerationConvention.cs rename to src/EFCore.SqlServer/Metadata/Conventions/SqlServerStoreGenerationConvention.cs index dedd4ecd0cf..25cc2e124a7 100644 --- a/src/EFCore.SqlServer/Metadata/Conventions/Internal/SqlServerStoreGenerationConvention.cs +++ b/src/EFCore.SqlServer/Metadata/Conventions/SqlServerStoreGenerationConvention.cs @@ -2,18 +2,36 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; +using JetBrains.Annotations; using Microsoft.EntityFrameworkCore.Diagnostics; -using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Metadata.Builders; -using Microsoft.EntityFrameworkCore.Metadata.Conventions; -using Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal; -using Microsoft.EntityFrameworkCore.Metadata.Internal; +using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure; using Microsoft.EntityFrameworkCore.SqlServer.Metadata.Internal; -namespace Microsoft.EntityFrameworkCore.SqlServer.Metadata.Conventions.Internal +// ReSharper disable once CheckNamespace +namespace Microsoft.EntityFrameworkCore.Metadata.Conventions { + /// + /// 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 class SqlServerStoreGenerationConvention : StoreGenerationConvention { + /// + /// 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 SqlServerStoreGenerationConvention( + [NotNull] ProviderConventionSetBuilderDependencies dependencies, + [NotNull] RelationalConventionSetBuilderDependencies relationalDependencies) + : base(dependencies, relationalDependencies) + { + } + /// /// Called after an annotation is changed on a property. /// diff --git a/src/EFCore.SqlServer/Metadata/Conventions/Internal/SqlServerValueGenerationStrategyConvention.cs b/src/EFCore.SqlServer/Metadata/Conventions/SqlServerValueGenerationStrategyConvention.cs similarity index 77% rename from src/EFCore.SqlServer/Metadata/Conventions/Internal/SqlServerValueGenerationStrategyConvention.cs rename to src/EFCore.SqlServer/Metadata/Conventions/SqlServerValueGenerationStrategyConvention.cs index dad303b5775..d8c857c661d 100644 --- a/src/EFCore.SqlServer/Metadata/Conventions/Internal/SqlServerValueGenerationStrategyConvention.cs +++ b/src/EFCore.SqlServer/Metadata/Conventions/SqlServerValueGenerationStrategyConvention.cs @@ -2,12 +2,11 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using JetBrains.Annotations; -using Microsoft.EntityFrameworkCore.Diagnostics; -using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Metadata.Builders; -using Microsoft.EntityFrameworkCore.Metadata.Conventions; +using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure; -namespace Microsoft.EntityFrameworkCore.SqlServer.Metadata.Conventions.Internal +// ReSharper disable once CheckNamespace +namespace Microsoft.EntityFrameworkCore.Metadata.Conventions { /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -23,18 +22,15 @@ public class SqlServerValueGenerationStrategyConvention : IModelInitializedConve /// 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 SqlServerValueGenerationStrategyConvention([NotNull] IDiagnosticsLogger logger) + public SqlServerValueGenerationStrategyConvention([NotNull] ProviderConventionSetBuilderDependencies dependencies) { - Logger = logger; + Dependencies = dependencies; } /// - /// 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. + /// Parameter object containing service dependencies. /// - protected virtual IDiagnosticsLogger Logger { get; } + protected virtual ProviderConventionSetBuilderDependencies Dependencies { get; } /// /// Called after a model is initialized. diff --git a/src/EFCore.SqlServer/Metadata/Conventions/Internal/SqlServerValueGeneratorConvention.cs b/src/EFCore.SqlServer/Metadata/Conventions/SqlServerValueGeneratorConvention.cs similarity index 71% rename from src/EFCore.SqlServer/Metadata/Conventions/Internal/SqlServerValueGeneratorConvention.cs rename to src/EFCore.SqlServer/Metadata/Conventions/SqlServerValueGeneratorConvention.cs index 46d24e271c2..e88443d59e4 100644 --- a/src/EFCore.SqlServer/Metadata/Conventions/Internal/SqlServerValueGeneratorConvention.cs +++ b/src/EFCore.SqlServer/Metadata/Conventions/SqlServerValueGeneratorConvention.cs @@ -2,14 +2,12 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using JetBrains.Annotations; -using Microsoft.EntityFrameworkCore.Diagnostics; -using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Metadata.Builders; -using Microsoft.EntityFrameworkCore.Metadata.Conventions; -using Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal; +using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure; using Microsoft.EntityFrameworkCore.SqlServer.Metadata.Internal; -namespace Microsoft.EntityFrameworkCore.SqlServer.Metadata.Conventions.Internal +// ReSharper disable once CheckNamespace +namespace Microsoft.EntityFrameworkCore.Metadata.Conventions { /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -25,8 +23,10 @@ public class SqlServerValueGeneratorConvention : RelationalValueGeneratorConvent /// 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 SqlServerValueGeneratorConvention([NotNull] IDiagnosticsLogger logger) - : base(logger) + public SqlServerValueGeneratorConvention( + [NotNull] ProviderConventionSetBuilderDependencies dependencies, + [NotNull] RelationalConventionSetBuilderDependencies relationalDependencies) + : base(dependencies, relationalDependencies) { } @@ -59,9 +59,17 @@ public override void ProcessPropertyAnnotationChanged( /// /// The property. /// The store value generation strategy to set for the given property. - public override ValueGenerated? GetValueGenerated(IConventionProperty property) - => base.GetValueGenerated(property) - ?? (property.GetSqlServerValueGenerationStrategyConfigurationSource() != null + protected override ValueGenerated? GetValueGenerated(IConventionProperty property) + => GetValueGenerated((IProperty)property); + + /// + /// Returns the store value generation strategy to set for the given property. + /// + /// The property. + /// The store value generation strategy to set for the given property. + public static new ValueGenerated? GetValueGenerated([NotNull] IProperty property) + => RelationalValueGeneratorConvention.GetValueGenerated(property) + ?? ((property as IConventionProperty)?.GetSqlServerValueGenerationStrategyConfigurationSource() != null && property.GetSqlServerValueGenerationStrategy() != null ? ValueGenerated.OnAdd : (ValueGenerated?)null); diff --git a/src/EFCore.Sqlite.Core/Metadata/Conventions/SqliteConventionSetBuilder.cs b/src/EFCore.Sqlite.Core/Metadata/Conventions/SqliteConventionSetBuilder.cs index b104cb914dc..08f74c02feb 100644 --- a/src/EFCore.Sqlite.Core/Metadata/Conventions/SqliteConventionSetBuilder.cs +++ b/src/EFCore.Sqlite.Core/Metadata/Conventions/SqliteConventionSetBuilder.cs @@ -5,6 +5,7 @@ using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure; using Microsoft.Extensions.DependencyInjection; +// ReSharper disable once CheckNamespace namespace Microsoft.EntityFrameworkCore.Metadata.Conventions { /// diff --git a/src/EFCore/Infrastructure/IModelSource.cs b/src/EFCore/Infrastructure/IModelSource.cs index 45783e7ab08..b83faf9f885 100644 --- a/src/EFCore/Infrastructure/IModelSource.cs +++ b/src/EFCore/Infrastructure/IModelSource.cs @@ -2,7 +2,6 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using JetBrains.Annotations; -using Microsoft.EntityFrameworkCore.Diagnostics; using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure; using Microsoft.Extensions.DependencyInjection; @@ -31,13 +30,9 @@ public interface IModelSource /// /// The context the model is being produced for. /// The convention set to use when creating the model. - /// The validator to verify the model can be successfully used with the context. - /// The validation logger to use. /// The model to be used. IModel GetModel( [NotNull] DbContext context, - [NotNull] IConventionSetBuilder conventionSetBuilder, - [NotNull] IModelValidator validator, - [NotNull] IDiagnosticsLogger validationLogger); + [NotNull] IConventionSetBuilder conventionSetBuilder); } } diff --git a/src/EFCore/Infrastructure/ModelCustomizer.cs b/src/EFCore/Infrastructure/ModelCustomizer.cs index 1c6e0585aeb..4e16d35ab96 100644 --- a/src/EFCore/Infrastructure/ModelCustomizer.cs +++ b/src/EFCore/Infrastructure/ModelCustomizer.cs @@ -1,6 +1,7 @@ // 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 JetBrains.Annotations; using Microsoft.EntityFrameworkCore.Utilities; using Microsoft.Extensions.DependencyInjection; @@ -9,7 +10,7 @@ namespace Microsoft.EntityFrameworkCore.Infrastructure { /// /// - /// Builds the model for a given context. This default implementation builds the model by calling + /// Builds the model for a given context. This implementation builds the model by calling /// on the context. /// /// @@ -53,7 +54,7 @@ public ModelCustomizer([NotNull] ModelCustomizerDependencies dependencies) /// public virtual void Customize(ModelBuilder modelBuilder, DbContext context) { - FindSets(modelBuilder, context); + FindSets(modelBuilder, context.GetType()); context.OnModelCreating(modelBuilder); } @@ -62,10 +63,10 @@ public virtual void Customize(ModelBuilder modelBuilder, DbContext context) /// Adds the entity types found in properties on the context to the model. /// /// The being used to build the model. - /// The context to find properties on. - protected virtual void FindSets([NotNull] ModelBuilder modelBuilder, [NotNull] DbContext context) + /// The context type to find properties on. + protected virtual void FindSets([NotNull] ModelBuilder modelBuilder, [NotNull] Type contextType) { - foreach (var setInfo in Dependencies.SetFinder.FindSets(context)) + foreach (var setInfo in Dependencies.SetFinder.FindSets(contextType)) { if (setInfo.IsKeyless) { diff --git a/src/EFCore/Infrastructure/ModelSource.cs b/src/EFCore/Infrastructure/ModelSource.cs index dc7e32d4d8c..8857954db9f 100644 --- a/src/EFCore/Infrastructure/ModelSource.cs +++ b/src/EFCore/Infrastructure/ModelSource.cs @@ -5,10 +5,8 @@ using System.Collections.Concurrent; using System.Threading; using JetBrains.Annotations; -using Microsoft.EntityFrameworkCore.Diagnostics; using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure; -using Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal; using Microsoft.EntityFrameworkCore.Utilities; using Microsoft.Extensions.DependencyInjection; @@ -56,19 +54,15 @@ public ModelSource([NotNull] ModelSourceDependencies dependencies) /// /// The context the model is being produced for. /// The convention set to use when creating the model. - /// The validator to verify the model can be successfully used with the context. - /// The validation loggers to use. /// The model to be used. public virtual IModel GetModel( DbContext context, - IConventionSetBuilder conventionSetBuilder, - IModelValidator validator, - IDiagnosticsLogger validationLogger) + IConventionSetBuilder conventionSetBuilder) => _models.GetOrAdd( Dependencies.ModelCacheKeyFactory.Create(context), // Using a Lazy here so that OnModelCreating, etc. really only gets called once, since it may not be thread safe. k => new Lazy( - () => CreateModel(context, conventionSetBuilder, validator, validationLogger), + () => CreateModel(context, conventionSetBuilder), LazyThreadSafetyMode.ExecutionAndPublication)).Value; /// @@ -76,23 +70,14 @@ public virtual IModel GetModel( /// /// The context the model is being produced for. /// The convention set to use when creating the model. - /// The validator to verify the model can be successfully used with the context. - /// The validation loggers to use. /// The model to be used. protected virtual IModel CreateModel( [NotNull] DbContext context, - [NotNull] IConventionSetBuilder conventionSetBuilder, - [NotNull] IModelValidator validator, - [NotNull] IDiagnosticsLogger validationLogger) + [NotNull] IConventionSetBuilder conventionSetBuilder) { Check.NotNull(context, nameof(context)); - Check.NotNull(validator, nameof(validator)); - Check.NotNull(validationLogger, nameof(validationLogger)); - var conventionSet = conventionSetBuilder.CreateConventionSet(); - conventionSet.ModelFinalizedConventions.Add(new ValidatingConvention(validator, validationLogger)); - - var modelBuilder = new ModelBuilder(conventionSet); + var modelBuilder = new ModelBuilder(conventionSetBuilder.CreateConventionSet()); Dependencies.ModelCustomizer.Customize(modelBuilder, context); diff --git a/src/EFCore/Internal/DbContextServices.cs b/src/EFCore/Internal/DbContextServices.cs index d6e19b467df..e89d192f6c3 100644 --- a/src/EFCore/Internal/DbContextServices.cs +++ b/src/EFCore/Internal/DbContextServices.cs @@ -83,9 +83,7 @@ private IModel CreateModel() return _scopedProvider.GetService().GetModel( _currentContext.Context, - _scopedProvider.GetService(), - _scopedProvider.GetService(), - _scopedProvider.GetService>()); + _scopedProvider.GetService()); } finally { diff --git a/src/EFCore/Internal/DbSetFinder.cs b/src/EFCore/Internal/DbSetFinder.cs index 9737c5015a5..ef55bb6ca67 100644 --- a/src/EFCore/Internal/DbSetFinder.cs +++ b/src/EFCore/Internal/DbSetFinder.cs @@ -35,10 +35,10 @@ private readonly ConcurrentDictionary> _cache /// 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 virtual IReadOnlyList FindSets(DbContext context) - => _cache.GetOrAdd(context.GetType(), FindSets); + public virtual IReadOnlyList FindSets(Type contextType) + => _cache.GetOrAdd(contextType, FindSetsNonCached); - private static DbSetProperty[] FindSets(Type contextType) + private static DbSetProperty[] FindSetsNonCached(Type contextType) { var factory = new ClrPropertySetterFactory(); diff --git a/src/EFCore/Internal/DbSetFinderExtensions.cs b/src/EFCore/Internal/DbSetFinderExtensions.cs index 863bbc93801..4f55e0c18d6 100644 --- a/src/EFCore/Internal/DbSetFinderExtensions.cs +++ b/src/EFCore/Internal/DbSetFinderExtensions.cs @@ -22,11 +22,11 @@ public static class DbSetFinderExtensions /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public static IDictionary CreateClrTypeDbSetMapping( - [NotNull] this IDbSetFinder setFinder, [NotNull] DbContext context) + [NotNull] this IDbSetFinder setFinder, [NotNull] Type contextType) { var sets = new Dictionary(); var alreadySeen = new HashSet(); - foreach (var set in setFinder.FindSets(context)) + foreach (var set in setFinder.FindSets(contextType)) { if (!alreadySeen.Contains(set.ClrType)) { diff --git a/src/EFCore/Internal/DbSetInitializer.cs b/src/EFCore/Internal/DbSetInitializer.cs index a5546bef42b..00999f376b3 100644 --- a/src/EFCore/Internal/DbSetInitializer.cs +++ b/src/EFCore/Internal/DbSetInitializer.cs @@ -47,7 +47,7 @@ public DbSetInitializer( /// public virtual void InitializeSets(DbContext context) { - foreach (var setInfo in _setFinder.FindSets(context).Where(p => p.Setter != null)) + foreach (var setInfo in _setFinder.FindSets(context.GetType()).Where(p => p.Setter != null)) { setInfo.Setter.SetClrValue( context, diff --git a/src/EFCore/Internal/IDbSetFinder.cs b/src/EFCore/Internal/IDbSetFinder.cs index 6a40c9e8af7..94110ec7715 100644 --- a/src/EFCore/Internal/IDbSetFinder.cs +++ b/src/EFCore/Internal/IDbSetFinder.cs @@ -1,6 +1,7 @@ // 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.Collections.Generic; using JetBrains.Annotations; using Microsoft.Extensions.DependencyInjection; @@ -28,6 +29,6 @@ public interface IDbSetFinder /// 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. /// - IReadOnlyList FindSets([NotNull] DbContext context); + IReadOnlyList FindSets([NotNull] Type contextType); } } diff --git a/src/EFCore/Metadata/Conventions/Internal/BackingFieldConvention.cs b/src/EFCore/Metadata/Conventions/BackingFieldConvention.cs similarity index 92% rename from src/EFCore/Metadata/Conventions/Internal/BackingFieldConvention.cs rename to src/EFCore/Metadata/Conventions/BackingFieldConvention.cs index 862c704d5b4..745b25eb883 100644 --- a/src/EFCore/Metadata/Conventions/Internal/BackingFieldConvention.cs +++ b/src/EFCore/Metadata/Conventions/BackingFieldConvention.cs @@ -9,9 +9,10 @@ using Microsoft.EntityFrameworkCore.Diagnostics; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure; using Microsoft.EntityFrameworkCore.Metadata.Internal; -namespace Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal +namespace Microsoft.EntityFrameworkCore.Metadata.Conventions { /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -27,18 +28,15 @@ public class BackingFieldConvention : IPropertyAddedConvention, INavigationAdded /// 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 BackingFieldConvention([NotNull] IDiagnosticsLogger logger) + public BackingFieldConvention([NotNull] ProviderConventionSetBuilderDependencies dependencies) { - Logger = logger; + Dependencies = dependencies; } /// - /// 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. + /// Parameter object containing service dependencies. /// - protected virtual IDiagnosticsLogger Logger { get; } + protected virtual ProviderConventionSetBuilderDependencies Dependencies { get; } /// /// Called after a property is added to the entity type. diff --git a/src/EFCore/Metadata/Conventions/Internal/BaseTypeDiscoveryConvention.cs b/src/EFCore/Metadata/Conventions/BaseTypeDiscoveryConvention.cs similarity index 90% rename from src/EFCore/Metadata/Conventions/Internal/BaseTypeDiscoveryConvention.cs rename to src/EFCore/Metadata/Conventions/BaseTypeDiscoveryConvention.cs index 31d54ad7e36..d29ceffb83c 100644 --- a/src/EFCore/Metadata/Conventions/Internal/BaseTypeDiscoveryConvention.cs +++ b/src/EFCore/Metadata/Conventions/BaseTypeDiscoveryConvention.cs @@ -2,11 +2,11 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using JetBrains.Annotations; -using Microsoft.EntityFrameworkCore.Diagnostics; using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure; using Microsoft.EntityFrameworkCore.Metadata.Internal; -namespace Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal +namespace Microsoft.EntityFrameworkCore.Metadata.Conventions { /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -22,8 +22,8 @@ public class BaseTypeDiscoveryConvention : InheritanceDiscoveryConventionBase, I /// 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 BaseTypeDiscoveryConvention([NotNull] IDiagnosticsLogger logger) - : base(logger) + public BaseTypeDiscoveryConvention([NotNull] ProviderConventionSetBuilderDependencies dependencies) + : base(dependencies) { } diff --git a/src/EFCore/Metadata/Conventions/Internal/CascadeDeleteConvention.cs b/src/EFCore/Metadata/Conventions/CascadeDeleteConvention.cs similarity index 81% rename from src/EFCore/Metadata/Conventions/Internal/CascadeDeleteConvention.cs rename to src/EFCore/Metadata/Conventions/CascadeDeleteConvention.cs index 5674bf211d6..499c493639c 100644 --- a/src/EFCore/Metadata/Conventions/Internal/CascadeDeleteConvention.cs +++ b/src/EFCore/Metadata/Conventions/CascadeDeleteConvention.cs @@ -2,10 +2,10 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using JetBrains.Annotations; -using Microsoft.EntityFrameworkCore.Diagnostics; using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure; -namespace Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal +namespace Microsoft.EntityFrameworkCore.Metadata.Conventions { /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -21,18 +21,15 @@ public class CascadeDeleteConvention : IForeignKeyAddedConvention, IForeignKeyRe /// 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 CascadeDeleteConvention([NotNull] IDiagnosticsLogger logger) + public CascadeDeleteConvention([NotNull] ProviderConventionSetBuilderDependencies dependencies) { - Logger = logger; + Dependencies = dependencies; } /// - /// 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. + /// Parameter object containing service dependencies. /// - protected virtual IDiagnosticsLogger Logger { get; } + protected virtual ProviderConventionSetBuilderDependencies Dependencies { get; } /// /// Called after a foreign key is added to the entity type. diff --git a/src/EFCore/Metadata/Conventions/Internal/ChangeTrackingStrategyConvention.cs b/src/EFCore/Metadata/Conventions/ChangeTrackingStrategyConvention.cs similarity index 73% rename from src/EFCore/Metadata/Conventions/Internal/ChangeTrackingStrategyConvention.cs rename to src/EFCore/Metadata/Conventions/ChangeTrackingStrategyConvention.cs index b4abab4aac2..4e0f6ee01f2 100644 --- a/src/EFCore/Metadata/Conventions/Internal/ChangeTrackingStrategyConvention.cs +++ b/src/EFCore/Metadata/Conventions/ChangeTrackingStrategyConvention.cs @@ -3,10 +3,10 @@ using JetBrains.Annotations; using Microsoft.EntityFrameworkCore.ChangeTracking.Internal; -using Microsoft.EntityFrameworkCore.Diagnostics; using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure; -namespace Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal +namespace Microsoft.EntityFrameworkCore.Metadata.Conventions { /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -22,18 +22,15 @@ public class ChangeTrackingStrategyConvention : IModelFinalizedConvention /// 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 ChangeTrackingStrategyConvention([NotNull] IDiagnosticsLogger logger) + public ChangeTrackingStrategyConvention([NotNull] ProviderConventionSetBuilderDependencies dependencies) { - Logger = logger; + Dependencies = dependencies; } /// - /// 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. + /// Parameter object containing service dependencies. /// - protected virtual IDiagnosticsLogger Logger { get; } + protected virtual ProviderConventionSetBuilderDependencies Dependencies { get; } /// /// Called after a model is finalized. diff --git a/src/EFCore/Metadata/Conventions/Internal/ConcurrencyCheckAttributeConvention.cs b/src/EFCore/Metadata/Conventions/ConcurrencyCheckAttributeConvention.cs similarity index 89% rename from src/EFCore/Metadata/Conventions/Internal/ConcurrencyCheckAttributeConvention.cs rename to src/EFCore/Metadata/Conventions/ConcurrencyCheckAttributeConvention.cs index fec2b22b2e4..cb2d8594097 100644 --- a/src/EFCore/Metadata/Conventions/Internal/ConcurrencyCheckAttributeConvention.cs +++ b/src/EFCore/Metadata/Conventions/ConcurrencyCheckAttributeConvention.cs @@ -4,11 +4,11 @@ using System.ComponentModel.DataAnnotations; using System.Reflection; using JetBrains.Annotations; -using Microsoft.EntityFrameworkCore.Diagnostics; using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure; using Microsoft.EntityFrameworkCore.Utilities; -namespace Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal +namespace Microsoft.EntityFrameworkCore.Metadata.Conventions { /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -24,8 +24,8 @@ public class ConcurrencyCheckAttributeConvention : PropertyAttributeConvention - public ConcurrencyCheckAttributeConvention([NotNull] IDiagnosticsLogger logger) - : base(logger) + public ConcurrencyCheckAttributeConvention([NotNull] ProviderConventionSetBuilderDependencies dependencies) + : base(dependencies) { } diff --git a/src/EFCore/Metadata/Conventions/Internal/ConstructorBindingConvention.cs b/src/EFCore/Metadata/Conventions/ConstructorBindingConvention.cs similarity index 86% rename from src/EFCore/Metadata/Conventions/Internal/ConstructorBindingConvention.cs rename to src/EFCore/Metadata/Conventions/ConstructorBindingConvention.cs index b1f3cb3f69e..565ffb7f9d6 100644 --- a/src/EFCore/Metadata/Conventions/Internal/ConstructorBindingConvention.cs +++ b/src/EFCore/Metadata/Conventions/ConstructorBindingConvention.cs @@ -9,9 +9,10 @@ using Microsoft.EntityFrameworkCore.Diagnostics; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure; using Microsoft.EntityFrameworkCore.Metadata.Internal; -namespace Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal +namespace Microsoft.EntityFrameworkCore.Metadata.Conventions { /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -21,29 +22,21 @@ namespace Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal /// public class ConstructorBindingConvention : IModelFinalizedConvention { - private readonly IConstructorBindingFactory _bindingFactory; - /// /// 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 ConstructorBindingConvention( - [NotNull] IConstructorBindingFactory bindingFactory, - [NotNull] IDiagnosticsLogger logger) + public ConstructorBindingConvention([NotNull] ProviderConventionSetBuilderDependencies dependencies) { - _bindingFactory = bindingFactory; - Logger = logger; + Dependencies = dependencies; } /// - /// 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. + /// Parameter object containing service dependencies. /// - protected virtual IDiagnosticsLogger Logger { get; } + protected virtual ProviderConventionSetBuilderDependencies Dependencies { get; } /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -68,7 +61,7 @@ public virtual void ProcessModelFinalized(IConventionModelBuilder modelBuilder, { // Trying to find the constructor with the most service properties // followed by the least scalar property parameters - if (_bindingFactory.TryBindConstructor(entityType, constructor, out var binding, out var failures)) + if (Dependencies.ConstructorBindingFactory.TryBindConstructor(entityType, constructor, out var binding, out var failures)) { var serviceParamCount = binding.ParameterBindings.OfType().Count(); var propertyParamCount = binding.ParameterBindings.Count - serviceParamCount; diff --git a/src/EFCore/Metadata/Conventions/ConventionSet.cs b/src/EFCore/Metadata/Conventions/ConventionSet.cs index b3a97afc2b1..b296fc09bc5 100644 --- a/src/EFCore/Metadata/Conventions/ConventionSet.cs +++ b/src/EFCore/Metadata/Conventions/ConventionSet.cs @@ -1,12 +1,12 @@ // 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.Collections.Generic; using JetBrains.Annotations; -using Microsoft.EntityFrameworkCore.Diagnostics; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure; -using Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal; +using Microsoft.EntityFrameworkCore.Utilities; namespace Microsoft.EntityFrameworkCore.Metadata.Conventions { @@ -113,8 +113,8 @@ public class ConventionSet /// /// Conventions to run when an annotation is changed on a foreign key. /// - public virtual IList ForeignKeyAnnotationChangedConventions { get; } = - new List(); + public virtual IList ForeignKeyAnnotationChangedConventions { get; } + = new List(); /// /// Conventions to run when a navigation property is added. @@ -139,8 +139,8 @@ public class ConventionSet /// /// Conventions to run when an annotation is changed on a key. /// - public virtual IList KeyAnnotationChangedConventions { get; } = - new List(); + public virtual IList KeyAnnotationChangedConventions { get; } + = new List(); /// /// Conventions to run when an index is added. @@ -155,14 +155,14 @@ public class ConventionSet /// /// Conventions to run when the uniqueness of an index is changed. /// - public virtual IList IndexUniquenessChangedConventions { get; } = - new List(); + public virtual IList IndexUniquenessChangedConventions { get; } + = new List(); /// /// Conventions to run when an annotation is changed on an index. /// - public virtual IList IndexAnnotationChangedConventions { get; } = - new List(); + public virtual IList IndexAnnotationChangedConventions { get; } + = new List(); /// /// Conventions to run when a property is added. @@ -187,6 +187,116 @@ public class ConventionSet public virtual IList PropertyAnnotationChangedConventions { get; } = new List(); + /// + /// Replaces an existing convention with a derived convention. + /// + /// The type of convention being replaced. + /// The type of the old convention. + /// The list of existing convention instances to scan. + /// The new convention. + /// true if the convention was replaced. + public static bool Replace( + [NotNull] IList conventionsList, + [NotNull] TImplementation newConvention) + where TImplementation : TConvention + { + Check.NotNull(conventionsList, nameof(conventionsList)); + Check.NotNull(newConvention, nameof(newConvention)); + + for (var i = 0; i < conventionsList.Count; i++) + { + if (conventionsList[i] is TImplementation) + { + conventionsList.RemoveAt(i); + conventionsList.Insert(i, newConvention); + return true; + } + } + + return false; + } + + /// + /// Adds a convention before an existing convention. + /// + /// The type of convention being added. + /// The list of existing convention instances to scan. + /// The new convention. + /// The type of the existing convention. + /// true if the convention was added. + public static bool AddBefore( + [NotNull] IList conventionsList, + [NotNull] TConvention newConvention, + [NotNull] Type existingConventionType) + { + Check.NotNull(conventionsList, nameof(conventionsList)); + Check.NotNull(newConvention, nameof(newConvention)); + + for (var i = 0; i < conventionsList.Count; i++) + { + if (existingConventionType.IsInstanceOfType(conventionsList[i])) + { + conventionsList.Insert(i, newConvention); + return true; + } + } + + return false; + } + + /// + /// Adds a convention after an existing convention. + /// + /// The type of convention being added. + /// The list of existing convention instances to scan. + /// The new convention. + /// The type of the existing convention. + /// true if the convention was added. + public static bool AddAfter( + [NotNull] IList conventionsList, + [NotNull] TConvention newConvention, + [NotNull] Type existingConventionType) + { + Check.NotNull(conventionsList, nameof(conventionsList)); + Check.NotNull(newConvention, nameof(newConvention)); + + for (var i = 0; i < conventionsList.Count; i++) + { + if (existingConventionType.IsInstanceOfType(conventionsList[i])) + { + conventionsList.Insert(i + 1, newConvention); + return true; + } + } + + return false; + } + + /// + /// Removes an existing convention. + /// + /// The type of convention being removed. + /// The list of existing convention instances to scan. + /// The type of the existing convention. + /// true if the convention was removed. + public static bool Remove( + [NotNull] IList conventionsList, + [NotNull] Type existingConventionType) + { + Check.NotNull(conventionsList, nameof(conventionsList)); + + for (var i = 0; i < conventionsList.Count; i++) + { + if (existingConventionType.IsInstanceOfType(conventionsList[i])) + { + conventionsList.RemoveAt(i); + return true; + } + } + + return false; + } + /// /// /// Call this method to build a for only core services when using @@ -199,15 +309,6 @@ public class ConventionSet /// /// The convention set. public static ConventionSet CreateConventionSet([NotNull] DbContext context) - { - var logger = context.GetService>(); - - var conventionSet = context.GetService().CreateConventionSet(); - - conventionSet.ModelFinalizedConventions.Add( - new ValidatingConvention(context.GetService(), logger)); - - return conventionSet; - } + => context.GetService().CreateConventionSet(); } } diff --git a/src/EFCore/Metadata/Conventions/Internal/DatabaseGeneratedAttributeConvention.cs b/src/EFCore/Metadata/Conventions/DatabaseGeneratedAttributeConvention.cs similarity index 90% rename from src/EFCore/Metadata/Conventions/Internal/DatabaseGeneratedAttributeConvention.cs rename to src/EFCore/Metadata/Conventions/DatabaseGeneratedAttributeConvention.cs index e66f8dd6963..b2daae26131 100644 --- a/src/EFCore/Metadata/Conventions/Internal/DatabaseGeneratedAttributeConvention.cs +++ b/src/EFCore/Metadata/Conventions/DatabaseGeneratedAttributeConvention.cs @@ -4,11 +4,11 @@ using System.ComponentModel.DataAnnotations.Schema; using System.Reflection; using JetBrains.Annotations; -using Microsoft.EntityFrameworkCore.Diagnostics; using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure; using Microsoft.EntityFrameworkCore.Utilities; -namespace Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal +namespace Microsoft.EntityFrameworkCore.Metadata.Conventions { /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -24,8 +24,8 @@ public class DatabaseGeneratedAttributeConvention : PropertyAttributeConvention< /// 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 DatabaseGeneratedAttributeConvention([NotNull] IDiagnosticsLogger logger) - : base(logger) + public DatabaseGeneratedAttributeConvention([NotNull] ProviderConventionSetBuilderDependencies dependencies) + : base(dependencies) { } diff --git a/src/EFCore/Metadata/Conventions/Internal/DerivedTypeDiscoveryConvention.cs b/src/EFCore/Metadata/Conventions/DerivedTypeDiscoveryConvention.cs similarity index 91% rename from src/EFCore/Metadata/Conventions/Internal/DerivedTypeDiscoveryConvention.cs rename to src/EFCore/Metadata/Conventions/DerivedTypeDiscoveryConvention.cs index 1b49af400a7..78a49ee6636 100644 --- a/src/EFCore/Metadata/Conventions/Internal/DerivedTypeDiscoveryConvention.cs +++ b/src/EFCore/Metadata/Conventions/DerivedTypeDiscoveryConvention.cs @@ -4,11 +4,11 @@ using System.Linq; using System.Reflection; using JetBrains.Annotations; -using Microsoft.EntityFrameworkCore.Diagnostics; using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure; using Microsoft.EntityFrameworkCore.Metadata.Internal; -namespace Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal +namespace Microsoft.EntityFrameworkCore.Metadata.Conventions { /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -24,8 +24,8 @@ public class DerivedTypeDiscoveryConvention : InheritanceDiscoveryConventionBase /// 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 DerivedTypeDiscoveryConvention([NotNull] IDiagnosticsLogger logger) - : base(logger) + public DerivedTypeDiscoveryConvention([NotNull] ProviderConventionSetBuilderDependencies dependencies) + : base(dependencies) { } diff --git a/src/EFCore/Metadata/Conventions/Internal/DiscriminatorConvention.cs b/src/EFCore/Metadata/Conventions/DiscriminatorConvention.cs similarity index 85% rename from src/EFCore/Metadata/Conventions/Internal/DiscriminatorConvention.cs rename to src/EFCore/Metadata/Conventions/DiscriminatorConvention.cs index e432f835fe1..d8051b6ecfa 100644 --- a/src/EFCore/Metadata/Conventions/Internal/DiscriminatorConvention.cs +++ b/src/EFCore/Metadata/Conventions/DiscriminatorConvention.cs @@ -4,11 +4,10 @@ using System.Collections.Generic; using System.Linq; using JetBrains.Annotations; -using Microsoft.EntityFrameworkCore.Diagnostics; using Microsoft.EntityFrameworkCore.Metadata.Builders; -using Microsoft.EntityFrameworkCore.Metadata.Internal; +using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure; -namespace Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal +namespace Microsoft.EntityFrameworkCore.Metadata.Conventions { /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -24,18 +23,15 @@ public class DiscriminatorConvention : IEntityTypeBaseTypeChangedConvention, IEn /// 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 DiscriminatorConvention([NotNull] IDiagnosticsLogger logger) + public DiscriminatorConvention([NotNull] ProviderConventionSetBuilderDependencies dependencies) { - Logger = logger; + Dependencies = dependencies; } /// - /// 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. + /// Parameter object containing service dependencies. /// - protected virtual IDiagnosticsLogger Logger { get; } + protected virtual ProviderConventionSetBuilderDependencies Dependencies { get; } /// /// Called after the base type of an entity type changes. @@ -122,7 +118,7 @@ public virtual void ProcessEntityTypeRemoved( /// doing so can result in application failures when updating to a new Entity Framework Core release. /// protected virtual void SetDefaultDiscriminatorValues( - IEnumerable entityTypes, IConventionDiscriminatorBuilder discriminator) + [NotNull] IEnumerable entityTypes, [NotNull] IConventionDiscriminatorBuilder discriminator) { foreach (var entityType in entityTypes) { diff --git a/src/EFCore/Metadata/Conventions/Internal/EntityTypeAttributeConvention.cs b/src/EFCore/Metadata/Conventions/EntityTypeAttributeConvention.cs similarity index 81% rename from src/EFCore/Metadata/Conventions/Internal/EntityTypeAttributeConvention.cs rename to src/EFCore/Metadata/Conventions/EntityTypeAttributeConvention.cs index e1a594c39ce..2899054a581 100644 --- a/src/EFCore/Metadata/Conventions/Internal/EntityTypeAttributeConvention.cs +++ b/src/EFCore/Metadata/Conventions/EntityTypeAttributeConvention.cs @@ -4,11 +4,12 @@ using System; using System.Reflection; using JetBrains.Annotations; -using Microsoft.EntityFrameworkCore.Diagnostics; using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal; using Microsoft.EntityFrameworkCore.Utilities; -namespace Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal +namespace Microsoft.EntityFrameworkCore.Metadata.Conventions { /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -25,18 +26,15 @@ public abstract class EntityTypeAttributeConvention : IEntityTypeAdd /// 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. /// - protected EntityTypeAttributeConvention([NotNull] IDiagnosticsLogger logger) + protected EntityTypeAttributeConvention([NotNull] ProviderConventionSetBuilderDependencies dependencies) { - Logger = logger; + Dependencies = dependencies; } /// - /// 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. + /// Parameter object containing service dependencies. /// - protected virtual IDiagnosticsLogger Logger { get; } + protected virtual ProviderConventionSetBuilderDependencies Dependencies { get; } /// /// Called after an entity type is added to the model. diff --git a/src/EFCore/Metadata/Conventions/Internal/ForeignKeyAttributeConvention.cs b/src/EFCore/Metadata/Conventions/ForeignKeyAttributeConvention.cs similarity index 90% rename from src/EFCore/Metadata/Conventions/Internal/ForeignKeyAttributeConvention.cs rename to src/EFCore/Metadata/Conventions/ForeignKeyAttributeConvention.cs index 0c69b1e1935..bec06cb841c 100644 --- a/src/EFCore/Metadata/Conventions/Internal/ForeignKeyAttributeConvention.cs +++ b/src/EFCore/Metadata/Conventions/ForeignKeyAttributeConvention.cs @@ -9,10 +9,11 @@ using JetBrains.Annotations; using Microsoft.EntityFrameworkCore.Diagnostics; using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure; using Microsoft.EntityFrameworkCore.Metadata.Internal; using Microsoft.EntityFrameworkCore.Utilities; -namespace Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal +namespace Microsoft.EntityFrameworkCore.Metadata.Conventions { /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -22,31 +23,21 @@ namespace Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal /// public class ForeignKeyAttributeConvention : IForeignKeyAddedConvention, IModelFinalizedConvention { - private readonly IMemberClassifier _memberClassifier; - /// /// 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 ForeignKeyAttributeConvention( - [NotNull] IMemberClassifier memberClassifier, - [NotNull] IDiagnosticsLogger logger) + public ForeignKeyAttributeConvention([NotNull] ProviderConventionSetBuilderDependencies dependencies) { - Check.NotNull(memberClassifier, nameof(memberClassifier)); - - _memberClassifier = memberClassifier; - Logger = logger; + Dependencies = dependencies; } /// - /// 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. + /// Parameter object containing service dependencies. /// - protected virtual IDiagnosticsLogger Logger { get; } + protected virtual ProviderConventionSetBuilderDependencies Dependencies { get; } /// /// Called after a foreign key is added to the entity type. @@ -69,7 +60,7 @@ var fkPropertyOnDependent if (fkPropertyOnDependent != null && fkPropertyOnPrincipal != null) { - Logger.ForeignKeyAttributesOnBothPropertiesWarning( + Dependencies.Logger.ForeignKeyAttributesOnBothPropertiesWarning( foreignKey.PrincipalToDependent, foreignKey.DependentToPrincipal, fkPropertyOnPrincipal, @@ -94,7 +85,7 @@ var fkPropertiesOnDependentToPrincipal if (fkPropertiesOnDependentToPrincipal != null && fkPropertiesOnPrincipalToDependent != null) { - Logger.ForeignKeyAttributesOnBothNavigationsWarning( + Dependencies.Logger.ForeignKeyAttributesOnBothNavigationsWarning( relationshipBuilder.Metadata.DependentToPrincipal, relationshipBuilder.Metadata.PrincipalToDependent); relationshipBuilder = SplitNavigationsToSeparateRelationships(relationshipBuilder); @@ -165,7 +156,7 @@ var fkPropertiesOnDependentToPrincipal if (fkPropertiesOnNavigation.Count != 1 || !Equals(fkPropertiesOnNavigation.First(), fkProperty.GetSimpleMemberName())) { - Logger.ConflictingForeignKeyAttributesOnNavigationAndPropertyWarning( + Dependencies.Logger.ConflictingForeignKeyAttributesOnNavigationAndPropertyWarning( fkPropertiesOnDependentToPrincipal != null ? relationshipBuilder.Metadata.DependentToPrincipal : relationshipBuilder.Metadata.PrincipalToDependent, @@ -248,8 +239,8 @@ var fkPropertiesOnDependentToPrincipal private static IConventionRelationshipBuilder SplitNavigationsToSeparateRelationships(IConventionRelationshipBuilder relationshipBuilder) { var foreignKey = relationshipBuilder.Metadata; - var dependentToPrincipalNavigationName = foreignKey.DependentToPrincipal?.Name; - var principalToDependentNavigationName = foreignKey.PrincipalToDependent?.Name; + var dependentToPrincipalNavigationName = foreignKey.DependentToPrincipal.Name; + var principalToDependentNavigationName = foreignKey.PrincipalToDependent.Name; if (GetInversePropertyAttribute(foreignKey.PrincipalToDependent) != null || GetInversePropertyAttribute(foreignKey.DependentToPrincipal) != null) @@ -356,14 +347,8 @@ private MemberInfo FindForeignKeyAttributeOnProperty(IConventionEntityType entit return candidateProperty; } - /// - /// 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. - /// - protected virtual Type FindCandidateNavigationPropertyType([NotNull] PropertyInfo propertyInfo) - => _memberClassifier.FindCandidateNavigationPropertyType(propertyInfo); + private Type FindCandidateNavigationPropertyType([NotNull] PropertyInfo propertyInfo) + => Dependencies.MemberClassifier.FindCandidateNavigationPropertyType(propertyInfo); private static IReadOnlyList FindCandidateDependentPropertiesThroughNavigation( IConventionRelationshipBuilder relationshipBuilder, diff --git a/src/EFCore/Metadata/Conventions/Internal/ForeignKeyIndexConvention.cs b/src/EFCore/Metadata/Conventions/ForeignKeyIndexConvention.cs similarity index 94% rename from src/EFCore/Metadata/Conventions/Internal/ForeignKeyIndexConvention.cs rename to src/EFCore/Metadata/Conventions/ForeignKeyIndexConvention.cs index 7ebcccd0eb4..41eaec72bac 100644 --- a/src/EFCore/Metadata/Conventions/Internal/ForeignKeyIndexConvention.cs +++ b/src/EFCore/Metadata/Conventions/ForeignKeyIndexConvention.cs @@ -8,8 +8,9 @@ using Microsoft.EntityFrameworkCore.Diagnostics.Internal; using Microsoft.EntityFrameworkCore.Internal; using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure; -namespace Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal +namespace Microsoft.EntityFrameworkCore.Metadata.Conventions { /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -36,18 +37,15 @@ public class ForeignKeyIndexConvention : /// 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 ForeignKeyIndexConvention([NotNull] IDiagnosticsLogger logger) + public ForeignKeyIndexConvention([NotNull] ProviderConventionSetBuilderDependencies dependencies) { - Logger = logger; + Dependencies = dependencies; } /// - /// 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. + /// Parameter object containing service dependencies. /// - protected virtual IDiagnosticsLogger Logger { get; } + protected virtual ProviderConventionSetBuilderDependencies Dependencies { get; } /// /// Called after a foreign key is added to the entity type. @@ -368,9 +366,9 @@ private static void RemoveIndex(IConventionIndex index) /// Additional information associated with convention execution. public virtual void ProcessModelFinalized(IConventionModelBuilder modelBuilder, IConventionContext context) { - var definition = CoreResources.LogRedundantIndexRemoved(Logger); - if (definition.GetLogBehavior(Logger) == WarningBehavior.Ignore - && !Logger.DiagnosticSource.IsEnabled(definition.EventId.Name)) + var definition = CoreResources.LogRedundantIndexRemoved(Dependencies.Logger); + if (definition.GetLogBehavior(Dependencies.Logger) == WarningBehavior.Ignore + && !Dependencies.Logger.DiagnosticSource.IsEnabled(definition.EventId.Name)) { return; } @@ -386,7 +384,7 @@ public virtual void ProcessModelFinalized(IConventionModelBuilder modelBuilder, { if (declaredForeignKey.Properties.Count != key.Properties.Count) { - Logger.RedundantIndexRemoved(declaredForeignKey.Properties, key.Properties); + Dependencies.Logger.RedundantIndexRemoved(declaredForeignKey.Properties, key.Properties); } } } @@ -398,7 +396,7 @@ public virtual void ProcessModelFinalized(IConventionModelBuilder modelBuilder, { if (declaredForeignKey.Properties.Count != existingIndex.Properties.Count) { - Logger.RedundantIndexRemoved(declaredForeignKey.Properties, existingIndex.Properties); + Dependencies.Logger.RedundantIndexRemoved(declaredForeignKey.Properties, existingIndex.Properties); } } } diff --git a/src/EFCore/Metadata/Conventions/Internal/ForeignKeyPropertyDiscoveryConvention.cs b/src/EFCore/Metadata/Conventions/ForeignKeyPropertyDiscoveryConvention.cs similarity index 97% rename from src/EFCore/Metadata/Conventions/Internal/ForeignKeyPropertyDiscoveryConvention.cs rename to src/EFCore/Metadata/Conventions/ForeignKeyPropertyDiscoveryConvention.cs index a462e94b75f..5ec3bbf6c8a 100644 --- a/src/EFCore/Metadata/Conventions/Internal/ForeignKeyPropertyDiscoveryConvention.cs +++ b/src/EFCore/Metadata/Conventions/ForeignKeyPropertyDiscoveryConvention.cs @@ -8,9 +8,10 @@ using JetBrains.Annotations; using Microsoft.EntityFrameworkCore.Diagnostics; using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure; using Microsoft.EntityFrameworkCore.Metadata.Internal; -namespace Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal +namespace Microsoft.EntityFrameworkCore.Metadata.Conventions { /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -40,18 +41,15 @@ public class ForeignKeyPropertyDiscoveryConvention : /// 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 ForeignKeyPropertyDiscoveryConvention([NotNull] IDiagnosticsLogger logger) + public ForeignKeyPropertyDiscoveryConvention([NotNull] ProviderConventionSetBuilderDependencies dependencies) { - Logger = logger; + Dependencies = dependencies; } /// - /// 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. + /// Parameter object containing service dependencies. /// - protected virtual IDiagnosticsLogger Logger { get; } + protected virtual ProviderConventionSetBuilderDependencies Dependencies { get; } /// /// Called after a foreign key is added to the entity type. @@ -386,7 +384,7 @@ private bool TryFindMatchingProperties( p => !p.IsShadowProperty() || p.GetConfigurationSource().Overrides(ConfigurationSource.DataAnnotation))) { - Logger.IncompatibleMatchingForeignKeyProperties(foreignKeyProperties, propertiesToReference); + Dependencies.Logger.IncompatibleMatchingForeignKeyProperties(foreignKeyProperties, propertiesToReference); } // Stop searching if match found, but is incompatible @@ -762,7 +760,7 @@ public virtual void ProcessModelFinalized(IConventionModelBuilder modelBuilder, if (conflictingShadowFk != null) { conflictingFkFound = true; - Logger.ConflictingShadowForeignKeysWarning(conflictingShadowFk); + Dependencies.Logger.ConflictingShadowForeignKeysWarning(conflictingShadowFk); } } } diff --git a/src/EFCore/Metadata/Conventions/Infrastructure/ProviderConventionSetBuilder.cs b/src/EFCore/Metadata/Conventions/Infrastructure/ProviderConventionSetBuilder.cs index 4c89b8d60a6..2a8cb9ae6e3 100644 --- a/src/EFCore/Metadata/Conventions/Infrastructure/ProviderConventionSetBuilder.cs +++ b/src/EFCore/Metadata/Conventions/Infrastructure/ProviderConventionSetBuilder.cs @@ -2,9 +2,7 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System.Collections.Generic; -using System.Linq; using JetBrains.Annotations; -using Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal; using Microsoft.EntityFrameworkCore.Utilities; using Microsoft.Extensions.DependencyInjection; @@ -57,43 +55,32 @@ public ProviderConventionSetBuilder([NotNull] ProviderConventionSetBuilderDepend public virtual ConventionSet CreateConventionSet() { var conventionSet = new ConventionSet(); - var logger = Dependencies.Logger; - var propertyDiscoveryConvention - = new PropertyDiscoveryConvention( - Dependencies.TypeMappingSource, logger); + var propertyDiscoveryConvention = new PropertyDiscoveryConvention(Dependencies); + var keyDiscoveryConvention = new KeyDiscoveryConvention(Dependencies); + var inversePropertyAttributeConvention = new InversePropertyAttributeConvention(Dependencies); + var relationshipDiscoveryConvention = new RelationshipDiscoveryConvention(Dependencies); + var servicePropertyDiscoveryConvention = new ServicePropertyDiscoveryConvention(Dependencies); - var keyDiscoveryConvention - = new KeyDiscoveryConvention(logger); - - var inversePropertyAttributeConvention - = new InversePropertyAttributeConvention(Dependencies.MemberClassifier, logger); - - var relationshipDiscoveryConvention - = new RelationshipDiscoveryConvention(Dependencies.MemberClassifier, logger); - - var servicePropertyDiscoveryConvention - = new ServicePropertyDiscoveryConvention(Dependencies.TypeMappingSource, Dependencies.ParameterBindingFactories, logger); - - conventionSet.EntityTypeAddedConventions.Add(new NotMappedEntityTypeAttributeConvention(logger)); - conventionSet.EntityTypeAddedConventions.Add(new OwnedEntityTypeAttributeConvention(logger)); - conventionSet.EntityTypeAddedConventions.Add(new NotMappedMemberAttributeConvention(logger)); - conventionSet.EntityTypeAddedConventions.Add(new BaseTypeDiscoveryConvention(logger)); + conventionSet.EntityTypeAddedConventions.Add(new NotMappedEntityTypeAttributeConvention(Dependencies)); + conventionSet.EntityTypeAddedConventions.Add(new OwnedEntityTypeAttributeConvention(Dependencies)); + conventionSet.EntityTypeAddedConventions.Add(new NotMappedMemberAttributeConvention(Dependencies)); + conventionSet.EntityTypeAddedConventions.Add(new BaseTypeDiscoveryConvention(Dependencies)); conventionSet.EntityTypeAddedConventions.Add(propertyDiscoveryConvention); conventionSet.EntityTypeAddedConventions.Add(servicePropertyDiscoveryConvention); conventionSet.EntityTypeAddedConventions.Add(keyDiscoveryConvention); conventionSet.EntityTypeAddedConventions.Add(inversePropertyAttributeConvention); conventionSet.EntityTypeAddedConventions.Add(relationshipDiscoveryConvention); - conventionSet.EntityTypeAddedConventions.Add(new DerivedTypeDiscoveryConvention(logger)); + conventionSet.EntityTypeAddedConventions.Add(new DerivedTypeDiscoveryConvention(Dependencies)); conventionSet.EntityTypeIgnoredConventions.Add(inversePropertyAttributeConvention); - var discriminatorConvention = new DiscriminatorConvention(logger); - conventionSet.EntityTypeRemovedConventions.Add(new OwnedTypesConvention(logger)); + var discriminatorConvention = new DiscriminatorConvention(Dependencies); + conventionSet.EntityTypeRemovedConventions.Add(new OwnedTypesConvention(Dependencies)); conventionSet.EntityTypeRemovedConventions.Add(discriminatorConvention); - var foreignKeyIndexConvention = new ForeignKeyIndexConvention(logger); - var valueGeneratorConvention = new ValueGeneratorConvention(logger); + var foreignKeyIndexConvention = new ForeignKeyIndexConvention(Dependencies); + var valueGeneratorConvention = new ValueGeneratorConvention(Dependencies); conventionSet.EntityTypeBaseTypeChangedConventions.Add(propertyDiscoveryConvention); conventionSet.EntityTypeBaseTypeChangedConventions.Add(servicePropertyDiscoveryConvention); @@ -104,22 +91,22 @@ var servicePropertyDiscoveryConvention conventionSet.EntityTypeBaseTypeChangedConventions.Add(valueGeneratorConvention); conventionSet.EntityTypeBaseTypeChangedConventions.Add(discriminatorConvention); - var foreignKeyPropertyDiscoveryConvention = new ForeignKeyPropertyDiscoveryConvention(logger); + var foreignKeyPropertyDiscoveryConvention = new ForeignKeyPropertyDiscoveryConvention(Dependencies); conventionSet.EntityTypeMemberIgnoredConventions.Add(inversePropertyAttributeConvention); conventionSet.EntityTypeMemberIgnoredConventions.Add(relationshipDiscoveryConvention); conventionSet.EntityTypeMemberIgnoredConventions.Add(foreignKeyPropertyDiscoveryConvention); conventionSet.EntityTypeMemberIgnoredConventions.Add(servicePropertyDiscoveryConvention); - var keyAttributeConvention = new KeyAttributeConvention(logger); - var backingFieldConvention = new BackingFieldConvention(logger); - var concurrencyCheckAttributeConvention = new ConcurrencyCheckAttributeConvention(logger); - var databaseGeneratedAttributeConvention = new DatabaseGeneratedAttributeConvention(logger); - var requiredPropertyAttributeConvention = new RequiredPropertyAttributeConvention(logger); - var nonNullableReferencePropertyConvention = new NonNullableReferencePropertyConvention(logger); - var maxLengthAttributeConvention = new MaxLengthAttributeConvention(logger); - var stringLengthAttributeConvention = new StringLengthAttributeConvention(logger); - var timestampAttributeConvention = new TimestampAttributeConvention(logger); + var keyAttributeConvention = new KeyAttributeConvention(Dependencies); + var backingFieldConvention = new BackingFieldConvention(Dependencies); + var concurrencyCheckAttributeConvention = new ConcurrencyCheckAttributeConvention(Dependencies); + var databaseGeneratedAttributeConvention = new DatabaseGeneratedAttributeConvention(Dependencies); + var requiredPropertyAttributeConvention = new RequiredPropertyAttributeConvention(Dependencies); + var nonNullableReferencePropertyConvention = new NonNullableReferencePropertyConvention(Dependencies); + var maxLengthAttributeConvention = new MaxLengthAttributeConvention(Dependencies); + var stringLengthAttributeConvention = new StringLengthAttributeConvention(Dependencies); + var timestampAttributeConvention = new TimestampAttributeConvention(Dependencies); conventionSet.PropertyAddedConventions.Add(backingFieldConvention); conventionSet.PropertyAddedConventions.Add(concurrencyCheckAttributeConvention); @@ -143,8 +130,8 @@ var servicePropertyDiscoveryConvention conventionSet.KeyRemovedConventions.Add(foreignKeyIndexConvention); conventionSet.KeyRemovedConventions.Add(keyDiscoveryConvention); - var cascadeDeleteConvention = new CascadeDeleteConvention(logger); - var foreignKeyAttributeConvention = new ForeignKeyAttributeConvention(Dependencies.MemberClassifier, logger); + var cascadeDeleteConvention = new CascadeDeleteConvention(Dependencies); + var foreignKeyAttributeConvention = new ForeignKeyAttributeConvention(Dependencies); conventionSet.ForeignKeyAddedConventions.Add(foreignKeyAttributeConvention); conventionSet.ForeignKeyAddedConventions.Add(foreignKeyPropertyDiscoveryConvention); @@ -169,24 +156,24 @@ var servicePropertyDiscoveryConvention conventionSet.ForeignKeyRequirednessChangedConventions.Add(cascadeDeleteConvention); conventionSet.ForeignKeyRequirednessChangedConventions.Add(foreignKeyPropertyDiscoveryConvention); - conventionSet.ForeignKeyOwnershipChangedConventions.Add(new NavigationEagerLoadingConvention(logger)); + conventionSet.ForeignKeyOwnershipChangedConventions.Add(new NavigationEagerLoadingConvention(Dependencies)); conventionSet.ForeignKeyOwnershipChangedConventions.Add(keyDiscoveryConvention); conventionSet.ForeignKeyOwnershipChangedConventions.Add(relationshipDiscoveryConvention); - conventionSet.ModelFinalizedConventions.Add(new ModelCleanupConvention(logger)); + conventionSet.ModelFinalizedConventions.Add(new ModelCleanupConvention(Dependencies)); conventionSet.ModelFinalizedConventions.Add(keyAttributeConvention); conventionSet.ModelFinalizedConventions.Add(foreignKeyAttributeConvention); - conventionSet.ModelFinalizedConventions.Add(new ChangeTrackingStrategyConvention(logger)); - conventionSet.ModelFinalizedConventions.Add(new ConstructorBindingConvention(Dependencies.ConstructorBindingFactory, logger)); - conventionSet.ModelFinalizedConventions.Add(new TypeMappingConvention(Dependencies.TypeMappingSource, logger)); + conventionSet.ModelFinalizedConventions.Add(new ChangeTrackingStrategyConvention(Dependencies)); + conventionSet.ModelFinalizedConventions.Add(new ConstructorBindingConvention(Dependencies)); + conventionSet.ModelFinalizedConventions.Add(new TypeMappingConvention(Dependencies)); conventionSet.ModelFinalizedConventions.Add(foreignKeyIndexConvention); - conventionSet.ModelFinalizedConventions.Add(foreignKeyPropertyDiscoveryConvention); conventionSet.ModelFinalizedConventions.Add(servicePropertyDiscoveryConvention); + conventionSet.ModelFinalizedConventions.Add(new ValidatingConvention(Dependencies)); conventionSet.NavigationAddedConventions.Add(backingFieldConvention); - conventionSet.NavigationAddedConventions.Add(new RequiredNavigationAttributeConvention(logger)); - conventionSet.NavigationAddedConventions.Add(new NonNullableNavigationConvention(logger)); + conventionSet.NavigationAddedConventions.Add(new RequiredNavigationAttributeConvention(Dependencies)); + conventionSet.NavigationAddedConventions.Add(new NonNullableNavigationConvention(Dependencies)); conventionSet.NavigationAddedConventions.Add(inversePropertyAttributeConvention); conventionSet.NavigationAddedConventions.Add(foreignKeyPropertyDiscoveryConvention); conventionSet.NavigationAddedConventions.Add(relationshipDiscoveryConvention); @@ -218,31 +205,16 @@ var servicePropertyDiscoveryConvention } /// - /// Helper method used to replace an existing convention implementation - /// with a new implementation. + /// Replaces an existing convention with a derived convention. /// - /// The type defining convention being replaced. - /// The type of the new implementation. + /// The type of convention being replaced. + /// The type of the old convention. /// The list of existing convention instances to scan. /// The new convention. - protected virtual void ReplaceConvention( + protected virtual bool ReplaceConvention( [NotNull] IList conventionsList, [NotNull] TImplementation newConvention) where TImplementation : TConvention - { - Check.NotNull(conventionsList, nameof(conventionsList)); - Check.NotNull(newConvention, nameof(newConvention)); - - var oldConvention = conventionsList.OfType().FirstOrDefault(); - if (oldConvention == null) - { - return; // Nothing to replace. - } - - var index = conventionsList.IndexOf(oldConvention); - - conventionsList.RemoveAt(index); - conventionsList.Insert(index, newConvention); - } + => ConventionSet.Replace(conventionsList, newConvention); } } diff --git a/src/EFCore/Metadata/Conventions/Infrastructure/ProviderConventionSetBuilderDependencies.cs b/src/EFCore/Metadata/Conventions/Infrastructure/ProviderConventionSetBuilderDependencies.cs index 3a9075ae5dd..5f60f37a7cf 100644 --- a/src/EFCore/Metadata/Conventions/Infrastructure/ProviderConventionSetBuilderDependencies.cs +++ b/src/EFCore/Metadata/Conventions/Infrastructure/ProviderConventionSetBuilderDependencies.cs @@ -1,6 +1,7 @@ // 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 JetBrains.Annotations; using Microsoft.EntityFrameworkCore.Diagnostics; using Microsoft.EntityFrameworkCore.Infrastructure; @@ -43,6 +44,8 @@ namespace Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure /// public sealed class ProviderConventionSetBuilderDependencies { + private readonly ICurrentDbContext _context; + /// /// /// Creates the service dependencies parameter object for a . @@ -67,32 +70,39 @@ public sealed class ProviderConventionSetBuilderDependencies /// The parameter binding factories. /// The member classifier. /// The model logger. + /// The model validation logger. /// The set finder. /// The current context instance. + /// The model validator. public ProviderConventionSetBuilderDependencies( [NotNull] ITypeMappingSource typeMappingSource, [NotNull] IConstructorBindingFactory constructorBindingFactory, [NotNull] IParameterBindingFactories parameterBindingFactories, [NotNull] IMemberClassifier memberClassifier, [NotNull] IDiagnosticsLogger logger, + [NotNull] IDiagnosticsLogger validationLogger, [NotNull] IDbSetFinder setFinder, - [NotNull] ICurrentDbContext context) + [NotNull] ICurrentDbContext context, + [NotNull] IModelValidator validator) { Check.NotNull(typeMappingSource, nameof(typeMappingSource)); Check.NotNull(constructorBindingFactory, nameof(constructorBindingFactory)); Check.NotNull(parameterBindingFactories, nameof(parameterBindingFactories)); Check.NotNull(memberClassifier, nameof(memberClassifier)); Check.NotNull(logger, nameof(logger)); + Check.NotNull(validationLogger, nameof(validationLogger)); Check.NotNull(setFinder, nameof(setFinder)); - Check.NotNull(context, nameof(context)); + Check.NotNull(validator, nameof(validator)); TypeMappingSource = typeMappingSource; ParameterBindingFactories = parameterBindingFactories; MemberClassifier = memberClassifier; ConstructorBindingFactory = constructorBindingFactory; Logger = logger; + ValidationLogger = validationLogger; SetFinder = setFinder; - Context = context; + _context = context; + ModelValidator = validator; } /// @@ -116,10 +126,15 @@ public ProviderConventionSetBuilderDependencies( public IConstructorBindingFactory ConstructorBindingFactory { get; } /// - /// The logger. + /// The model logger. /// public IDiagnosticsLogger Logger { get; } + /// + /// The model validation logger. + /// + public IDiagnosticsLogger ValidationLogger { get; } + /// /// The set finder. /// @@ -128,7 +143,12 @@ public ProviderConventionSetBuilderDependencies( /// /// The current context instance. /// - public ICurrentDbContext Context { get; } + public Type ContextType => _context.Context.GetType(); + + /// + /// The model validator. + /// + public IModelValidator ModelValidator { get; } /// /// Clones this dependency parameter object with one service replaced. @@ -137,7 +157,8 @@ public ProviderConventionSetBuilderDependencies( /// A new parameter object with the given service replaced. public ProviderConventionSetBuilderDependencies With([NotNull] ITypeMappingSource typeMappingSource) => new ProviderConventionSetBuilderDependencies( - typeMappingSource, ConstructorBindingFactory, ParameterBindingFactories, MemberClassifier, Logger, SetFinder, Context); + typeMappingSource, ConstructorBindingFactory, ParameterBindingFactories, MemberClassifier, Logger, ValidationLogger, + SetFinder, _context, ModelValidator); /// /// Clones this dependency parameter object with one service replaced. @@ -146,7 +167,8 @@ public ProviderConventionSetBuilderDependencies With([NotNull] ITypeMappingSourc /// A new parameter object with the given service replaced. public ProviderConventionSetBuilderDependencies With([NotNull] IConstructorBindingFactory constructorBindingFactory) => new ProviderConventionSetBuilderDependencies( - TypeMappingSource, constructorBindingFactory, ParameterBindingFactories, MemberClassifier, Logger, SetFinder, Context); + TypeMappingSource, constructorBindingFactory, ParameterBindingFactories, MemberClassifier, Logger, ValidationLogger, + SetFinder, _context, ModelValidator); /// /// Clones this dependency parameter object with one service replaced. @@ -155,7 +177,18 @@ public ProviderConventionSetBuilderDependencies With([NotNull] IConstructorBindi /// A new parameter object with the given service replaced. public ProviderConventionSetBuilderDependencies With([NotNull] IDiagnosticsLogger logger) => new ProviderConventionSetBuilderDependencies( - TypeMappingSource, ConstructorBindingFactory, ParameterBindingFactories, MemberClassifier, logger, SetFinder, Context); + TypeMappingSource, ConstructorBindingFactory, ParameterBindingFactories, MemberClassifier, logger, ValidationLogger, + SetFinder, _context, ModelValidator); + + /// + /// Clones this dependency parameter object with one service replaced. + /// + /// A replacement for the current dependency of this type. + /// A new parameter object with the given service replaced. + public ProviderConventionSetBuilderDependencies With([NotNull] IDiagnosticsLogger validationLogger) + => new ProviderConventionSetBuilderDependencies( + TypeMappingSource, ConstructorBindingFactory, ParameterBindingFactories, MemberClassifier, Logger, validationLogger, + SetFinder, _context, ModelValidator); /// /// Clones this dependency parameter object with one service replaced. @@ -164,7 +197,8 @@ public ProviderConventionSetBuilderDependencies With([NotNull] IDiagnosticsLogge /// A new parameter object with the given service replaced. public ProviderConventionSetBuilderDependencies With([NotNull] IParameterBindingFactories parameterBindingFactories) => new ProviderConventionSetBuilderDependencies( - TypeMappingSource, ConstructorBindingFactory, parameterBindingFactories, MemberClassifier, Logger, SetFinder, Context); + TypeMappingSource, ConstructorBindingFactory, parameterBindingFactories, MemberClassifier, Logger, ValidationLogger, + SetFinder, _context, ModelValidator); /// /// Clones this dependency parameter object with one service replaced. @@ -173,7 +207,8 @@ public ProviderConventionSetBuilderDependencies With([NotNull] IParameterBinding /// A new parameter object with the given service replaced. public ProviderConventionSetBuilderDependencies With([NotNull] IMemberClassifier memberClassifier) => new ProviderConventionSetBuilderDependencies( - TypeMappingSource, ConstructorBindingFactory, ParameterBindingFactories, memberClassifier, Logger, SetFinder, Context); + TypeMappingSource, ConstructorBindingFactory, ParameterBindingFactories, memberClassifier, Logger, ValidationLogger, + SetFinder, _context, ModelValidator); /// /// Clones this dependency parameter object with one service replaced. @@ -182,7 +217,8 @@ public ProviderConventionSetBuilderDependencies With([NotNull] IMemberClassifier /// A new parameter object with the given service replaced. public ProviderConventionSetBuilderDependencies With([NotNull] IDbSetFinder setFinder) => new ProviderConventionSetBuilderDependencies( - TypeMappingSource, ConstructorBindingFactory, ParameterBindingFactories, MemberClassifier, Logger, setFinder, Context); + TypeMappingSource, ConstructorBindingFactory, ParameterBindingFactories, MemberClassifier, Logger, ValidationLogger, + setFinder, _context, ModelValidator); /// /// Clones this dependency parameter object with one service replaced. @@ -191,6 +227,17 @@ public ProviderConventionSetBuilderDependencies With([NotNull] IDbSetFinder setF /// A new parameter object with the given service replaced. public ProviderConventionSetBuilderDependencies With([NotNull] ICurrentDbContext context) => new ProviderConventionSetBuilderDependencies( - TypeMappingSource, ConstructorBindingFactory, ParameterBindingFactories, MemberClassifier, Logger, SetFinder, context); + TypeMappingSource, ConstructorBindingFactory, ParameterBindingFactories, MemberClassifier, Logger, ValidationLogger, + SetFinder, context, ModelValidator); + + /// + /// Clones this dependency parameter object with one service replaced. + /// + /// A replacement for the current dependency of this type. + /// A new parameter object with the given service replaced. + public ProviderConventionSetBuilderDependencies With([NotNull] IModelValidator validator) + => new ProviderConventionSetBuilderDependencies( + TypeMappingSource, ConstructorBindingFactory, ParameterBindingFactories, MemberClassifier, Logger, ValidationLogger, + SetFinder, _context, validator); } } diff --git a/src/EFCore/Metadata/Conventions/Internal/InheritanceDiscoveryConventionBase.cs b/src/EFCore/Metadata/Conventions/InheritanceDiscoveryConventionBase.cs similarity index 76% rename from src/EFCore/Metadata/Conventions/Internal/InheritanceDiscoveryConventionBase.cs rename to src/EFCore/Metadata/Conventions/InheritanceDiscoveryConventionBase.cs index 27e282155b6..2d633f7b2e7 100644 --- a/src/EFCore/Metadata/Conventions/Internal/InheritanceDiscoveryConventionBase.cs +++ b/src/EFCore/Metadata/Conventions/InheritanceDiscoveryConventionBase.cs @@ -3,10 +3,10 @@ using System.Reflection; using JetBrains.Annotations; -using Microsoft.EntityFrameworkCore.Diagnostics; +using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure; using Microsoft.EntityFrameworkCore.Utilities; -namespace Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal +namespace Microsoft.EntityFrameworkCore.Metadata.Conventions { /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -22,18 +22,15 @@ public abstract class InheritanceDiscoveryConventionBase /// 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. /// - protected InheritanceDiscoveryConventionBase([NotNull] IDiagnosticsLogger logger) + protected InheritanceDiscoveryConventionBase([NotNull] ProviderConventionSetBuilderDependencies dependencies) { - Logger = logger; + Dependencies = dependencies; } /// - /// 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. + /// Parameter object containing service dependencies. /// - protected virtual IDiagnosticsLogger Logger { get; } + protected virtual ProviderConventionSetBuilderDependencies Dependencies { get; } /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore/Metadata/Conventions/Internal/InversePropertyAttributeConvention.cs b/src/EFCore/Metadata/Conventions/InversePropertyAttributeConvention.cs similarity index 95% rename from src/EFCore/Metadata/Conventions/Internal/InversePropertyAttributeConvention.cs rename to src/EFCore/Metadata/Conventions/InversePropertyAttributeConvention.cs index d00e72d56e0..a52fc73f4e2 100644 --- a/src/EFCore/Metadata/Conventions/Internal/InversePropertyAttributeConvention.cs +++ b/src/EFCore/Metadata/Conventions/InversePropertyAttributeConvention.cs @@ -11,9 +11,10 @@ using Microsoft.EntityFrameworkCore.Diagnostics; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure; using Microsoft.EntityFrameworkCore.Metadata.Internal; -namespace Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal +namespace Microsoft.EntityFrameworkCore.Metadata.Conventions { /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -30,21 +31,11 @@ public class InversePropertyAttributeConvention : /// 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 InversePropertyAttributeConvention( - [NotNull] IMemberClassifier memberClassifier, - [NotNull] IDiagnosticsLogger logger) - : base(memberClassifier, logger) + public InversePropertyAttributeConvention([NotNull] ProviderConventionSetBuilderDependencies dependencies) + : base(dependencies) { } - /// - /// 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 const string InverseNavigationsAnnotationName = "InversePropertyAttributeConvention:InverseNavigations"; - /// /// 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 @@ -185,7 +176,7 @@ private IConventionRelationshipBuilder ConfigureInverseNavigation( && ownership.PrincipalEntityType == targetEntityTypeBuilder.Metadata && ownership.PrincipalToDependent.GetIdentifyingMemberInfo() != inverseNavigationPropertyInfo) { - Logger.NonOwnershipInverseNavigationWarning( + Dependencies.Logger.NonOwnershipInverseNavigationWarning( entityType, navigationMemberInfo, targetEntityTypeBuilder.Metadata, inverseNavigationPropertyInfo, ownership.PrincipalToDependent.GetIdentifyingMemberInfo()); @@ -196,7 +187,7 @@ private IConventionRelationshipBuilder ConfigureInverseNavigation( && entityType.DefiningEntityType == targetEntityTypeBuilder.Metadata && entityType.DefiningNavigationName != inverseNavigationPropertyInfo.GetSimpleMemberName()) { - Logger.NonDefiningInverseNavigationWarning( + Dependencies.Logger.NonDefiningInverseNavigationWarning( entityType, navigationMemberInfo, targetEntityTypeBuilder.Metadata, inverseNavigationPropertyInfo, entityType.DefiningEntityType.GetRuntimeProperties()[entityType.DefiningNavigationName]); @@ -366,7 +357,7 @@ public virtual void ProcessModelFinalized(IConventionModelBuilder modelBuilder, inverseNavigation.Value); if (ambiguousInverse != null) { - Logger.MultipleInversePropertiesSameTargetWarning( + Dependencies.Logger.MultipleInversePropertiesSameTargetWarning( new[] { Tuple.Create( @@ -546,12 +537,12 @@ private static IConventionEntityType FindActualEntityType(IConventionEntityType private static Dictionary> GetInverseNavigations( IConventionAnnotatable entityType) - => entityType.FindAnnotation(InverseNavigationsAnnotationName)?.Value + => entityType.FindAnnotation(CoreAnnotationNames.InverseNavigations)?.Value as Dictionary>; private static void SetInverseNavigations( IConventionAnnotatableBuilder entityTypeBuilder, Dictionary> inverseNavigations) - => entityTypeBuilder.HasAnnotation(InverseNavigationsAnnotationName, inverseNavigations); + => entityTypeBuilder.HasAnnotation(CoreAnnotationNames.InverseNavigations, inverseNavigations); } } diff --git a/src/EFCore/Metadata/Conventions/Internal/KeyAttributeConvention.cs b/src/EFCore/Metadata/Conventions/KeyAttributeConvention.cs similarity index 95% rename from src/EFCore/Metadata/Conventions/Internal/KeyAttributeConvention.cs rename to src/EFCore/Metadata/Conventions/KeyAttributeConvention.cs index b14e4ded24c..5d7295b57c3 100644 --- a/src/EFCore/Metadata/Conventions/Internal/KeyAttributeConvention.cs +++ b/src/EFCore/Metadata/Conventions/KeyAttributeConvention.cs @@ -9,10 +9,11 @@ using JetBrains.Annotations; using Microsoft.EntityFrameworkCore.Diagnostics; using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure; using Microsoft.EntityFrameworkCore.Metadata.Internal; using Microsoft.EntityFrameworkCore.Utilities; -namespace Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal +namespace Microsoft.EntityFrameworkCore.Metadata.Conventions { /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -28,8 +29,8 @@ public class KeyAttributeConvention : PropertyAttributeConvention, /// 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 KeyAttributeConvention([NotNull] IDiagnosticsLogger logger) - : base(logger) + public KeyAttributeConvention([NotNull] ProviderConventionSetBuilderDependencies dependencies) + : base(dependencies) { } diff --git a/src/EFCore/Metadata/Conventions/Internal/KeyDiscoveryConvention.cs b/src/EFCore/Metadata/Conventions/KeyDiscoveryConvention.cs similarity index 94% rename from src/EFCore/Metadata/Conventions/Internal/KeyDiscoveryConvention.cs rename to src/EFCore/Metadata/Conventions/KeyDiscoveryConvention.cs index fb46619ec44..7c4b7d87130 100644 --- a/src/EFCore/Metadata/Conventions/Internal/KeyDiscoveryConvention.cs +++ b/src/EFCore/Metadata/Conventions/KeyDiscoveryConvention.cs @@ -8,10 +8,11 @@ using JetBrains.Annotations; using Microsoft.EntityFrameworkCore.Diagnostics; using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure; using Microsoft.EntityFrameworkCore.Metadata.Internal; using Microsoft.EntityFrameworkCore.Utilities; -namespace Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal +namespace Microsoft.EntityFrameworkCore.Metadata.Conventions { /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -39,18 +40,15 @@ public class KeyDiscoveryConvention : /// 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 KeyDiscoveryConvention([NotNull] IDiagnosticsLogger logger) + public KeyDiscoveryConvention([NotNull] ProviderConventionSetBuilderDependencies dependencies) { - Logger = logger; + Dependencies = dependencies; } /// - /// 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. + /// Parameter object containing service dependencies. /// - protected virtual IDiagnosticsLogger Logger { get; } + protected virtual ProviderConventionSetBuilderDependencies Dependencies { get; } private void TryConfigurePrimaryKey(IConventionEntityTypeBuilder entityTypeBuilder) { @@ -84,7 +82,7 @@ private void TryConfigurePrimaryKey(IConventionEntityTypeBuilder entityTypeBuild keyProperties = (List)DiscoverKeyProperties(entityType, candidateProperties); if (keyProperties.Count > 1) { - Logger?.MultiplePrimaryKeyCandidates(keyProperties[0], keyProperties[1]); + Dependencies.Logger.MultiplePrimaryKeyCandidates(keyProperties[0], keyProperties[1]); return; } } diff --git a/src/EFCore/Metadata/Conventions/Internal/MaxLengthAttributeConvention.cs b/src/EFCore/Metadata/Conventions/MaxLengthAttributeConvention.cs similarity index 89% rename from src/EFCore/Metadata/Conventions/Internal/MaxLengthAttributeConvention.cs rename to src/EFCore/Metadata/Conventions/MaxLengthAttributeConvention.cs index 20808b3866b..6fb7ddbbd1c 100644 --- a/src/EFCore/Metadata/Conventions/Internal/MaxLengthAttributeConvention.cs +++ b/src/EFCore/Metadata/Conventions/MaxLengthAttributeConvention.cs @@ -4,11 +4,11 @@ using System.ComponentModel.DataAnnotations; using System.Reflection; using JetBrains.Annotations; -using Microsoft.EntityFrameworkCore.Diagnostics; using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure; using Microsoft.EntityFrameworkCore.Utilities; -namespace Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal +namespace Microsoft.EntityFrameworkCore.Metadata.Conventions { /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -24,8 +24,8 @@ public class MaxLengthAttributeConvention : PropertyAttributeConvention - public MaxLengthAttributeConvention([NotNull] IDiagnosticsLogger logger) - : base(logger) + public MaxLengthAttributeConvention([NotNull] ProviderConventionSetBuilderDependencies dependencies) + : base(dependencies) { } diff --git a/src/EFCore/Metadata/Conventions/Internal/ModelCleanupConvention.cs b/src/EFCore/Metadata/Conventions/ModelCleanupConvention.cs similarity index 78% rename from src/EFCore/Metadata/Conventions/Internal/ModelCleanupConvention.cs rename to src/EFCore/Metadata/Conventions/ModelCleanupConvention.cs index 59d2a7385c6..55ec8c852a8 100644 --- a/src/EFCore/Metadata/Conventions/Internal/ModelCleanupConvention.cs +++ b/src/EFCore/Metadata/Conventions/ModelCleanupConvention.cs @@ -4,11 +4,11 @@ using System.Collections.Generic; using System.Linq; using JetBrains.Annotations; -using Microsoft.EntityFrameworkCore.Diagnostics; using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure; using Microsoft.EntityFrameworkCore.Metadata.Internal; -namespace Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal +namespace Microsoft.EntityFrameworkCore.Metadata.Conventions { /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -24,18 +24,15 @@ public class ModelCleanupConvention : IModelFinalizedConvention /// 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 ModelCleanupConvention([NotNull] IDiagnosticsLogger logger) + public ModelCleanupConvention([NotNull] ProviderConventionSetBuilderDependencies dependencies) { - Logger = logger; + Dependencies = dependencies; } /// - /// 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. + /// Parameter object containing service dependencies. /// - protected virtual IDiagnosticsLogger Logger { get; } + protected virtual ProviderConventionSetBuilderDependencies Dependencies { get; } /// /// Called after a model is finalized. @@ -98,9 +95,9 @@ private void RemoveModelBuildingAnnotations(IConventionModelBuilder modelBuilder { foreach (var entityType in modelBuilder.Metadata.GetEntityTypes()) { - entityType.RemoveAnnotation(RelationshipDiscoveryConvention.AmbiguousNavigationsAnnotationName); - entityType.RemoveAnnotation(RelationshipDiscoveryConvention.NavigationCandidatesAnnotationName); - entityType.RemoveAnnotation(InversePropertyAttributeConvention.InverseNavigationsAnnotationName); + entityType.RemoveAnnotation(CoreAnnotationNames.AmbiguousNavigations); + entityType.RemoveAnnotation(CoreAnnotationNames.NavigationCandidates); + entityType.RemoveAnnotation(CoreAnnotationNames.InverseNavigations); } } } diff --git a/src/EFCore/Metadata/Conventions/Internal/NavigationAttributeEntityTypeConvention.cs b/src/EFCore/Metadata/Conventions/NavigationAttributeEntityTypeConvention.cs similarity index 94% rename from src/EFCore/Metadata/Conventions/Internal/NavigationAttributeEntityTypeConvention.cs rename to src/EFCore/Metadata/Conventions/NavigationAttributeEntityTypeConvention.cs index 95a3a023b1d..d1ed0c17738 100644 --- a/src/EFCore/Metadata/Conventions/Internal/NavigationAttributeEntityTypeConvention.cs +++ b/src/EFCore/Metadata/Conventions/NavigationAttributeEntityTypeConvention.cs @@ -5,13 +5,13 @@ using System.Linq; using System.Reflection; using JetBrains.Annotations; -using Microsoft.EntityFrameworkCore.Diagnostics; using Microsoft.EntityFrameworkCore.Internal; using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal; using Microsoft.EntityFrameworkCore.Metadata.Internal; -using Microsoft.EntityFrameworkCore.Utilities; -namespace Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal +namespace Microsoft.EntityFrameworkCore.Metadata.Conventions { /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -27,22 +27,15 @@ public abstract class NavigationAttributeEntityTypeConvention : IEntityTypeMemberIgnoredConvention where TAttribute : Attribute { - private readonly IMemberClassifier _memberClassifier; - /// /// 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. /// - protected NavigationAttributeEntityTypeConvention( - [NotNull] IMemberClassifier memberClassifier, - [NotNull] IDiagnosticsLogger logger) - : base(logger) + protected NavigationAttributeEntityTypeConvention([NotNull] ProviderConventionSetBuilderDependencies dependencies) + : base(dependencies) { - Check.NotNull(memberClassifier, nameof(memberClassifier)); - - _memberClassifier = memberClassifier; } /// @@ -196,11 +189,11 @@ public virtual void ProcessEntityTypeMemberIgnored( /// doing so can result in application failures when updating to a new Entity Framework Core release. /// protected virtual Type FindCandidateNavigationPropertyType([NotNull] PropertyInfo propertyInfo) - => _memberClassifier.FindCandidateNavigationPropertyType(propertyInfo); + => Dependencies.MemberClassifier.FindCandidateNavigationPropertyType(propertyInfo); private Type FindCandidateNavigationWithAttributePropertyType([NotNull] PropertyInfo propertyInfo) { - var targetClrType = _memberClassifier.FindCandidateNavigationPropertyType(propertyInfo); + var targetClrType = Dependencies.MemberClassifier.FindCandidateNavigationPropertyType(propertyInfo); return targetClrType == null || !Attribute.IsDefined(propertyInfo, typeof(TAttribute), inherit: true) ? null @@ -257,7 +250,7 @@ public override void ProcessNavigationAdded( /// public virtual void ProcessEntityTypeBaseTypeChanged( [NotNull] IConventionEntityTypeBuilder entityTypeBuilder, - IConventionEntityType newBaseType, + [CanBeNull] IConventionEntityType newBaseType, [CanBeNull] IConventionEntityType oldBaseType, [NotNull] MemberInfo navigationMemberInfo, [NotNull] Type targetClrType, diff --git a/src/EFCore/Metadata/Conventions/Internal/NavigationAttributeNavigationConvention.cs b/src/EFCore/Metadata/Conventions/NavigationAttributeNavigationConvention.cs similarity index 87% rename from src/EFCore/Metadata/Conventions/Internal/NavigationAttributeNavigationConvention.cs rename to src/EFCore/Metadata/Conventions/NavigationAttributeNavigationConvention.cs index 120ff82bb33..d6874812b6d 100644 --- a/src/EFCore/Metadata/Conventions/Internal/NavigationAttributeNavigationConvention.cs +++ b/src/EFCore/Metadata/Conventions/NavigationAttributeNavigationConvention.cs @@ -6,12 +6,13 @@ using System.Linq; using System.Reflection; using JetBrains.Annotations; -using Microsoft.EntityFrameworkCore.Diagnostics; using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal; using Microsoft.EntityFrameworkCore.Metadata.Internal; using Microsoft.EntityFrameworkCore.Utilities; -namespace Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal +namespace Microsoft.EntityFrameworkCore.Metadata.Conventions { /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -28,18 +29,15 @@ public abstract class NavigationAttributeNavigationConvention : INav /// 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. /// - protected NavigationAttributeNavigationConvention([NotNull] IDiagnosticsLogger logger) + protected NavigationAttributeNavigationConvention([NotNull] ProviderConventionSetBuilderDependencies dependencies) { - Logger = logger; + Dependencies = dependencies; } /// - /// 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. + /// Parameter object containing service dependencies. /// - protected virtual IDiagnosticsLogger Logger { get; } + protected virtual ProviderConventionSetBuilderDependencies Dependencies { get; } /// /// Called after a navigation is added to the entity type. diff --git a/src/EFCore/Metadata/Conventions/Internal/NavigationEagerLoadingConvention.cs b/src/EFCore/Metadata/Conventions/NavigationEagerLoadingConvention.cs similarity index 72% rename from src/EFCore/Metadata/Conventions/Internal/NavigationEagerLoadingConvention.cs rename to src/EFCore/Metadata/Conventions/NavigationEagerLoadingConvention.cs index 724c831303e..8d75a109227 100644 --- a/src/EFCore/Metadata/Conventions/Internal/NavigationEagerLoadingConvention.cs +++ b/src/EFCore/Metadata/Conventions/NavigationEagerLoadingConvention.cs @@ -2,10 +2,10 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using JetBrains.Annotations; -using Microsoft.EntityFrameworkCore.Diagnostics; using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure; -namespace Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal +namespace Microsoft.EntityFrameworkCore.Metadata.Conventions { /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -21,18 +21,15 @@ public class NavigationEagerLoadingConvention : IForeignKeyOwnershipChangedConve /// 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 NavigationEagerLoadingConvention([NotNull] IDiagnosticsLogger logger) + public NavigationEagerLoadingConvention([NotNull] ProviderConventionSetBuilderDependencies dependencies) { - Logger = logger; + Dependencies = dependencies; } /// - /// 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. + /// Parameter object containing service dependencies. /// - protected virtual IDiagnosticsLogger Logger { get; } + protected virtual ProviderConventionSetBuilderDependencies Dependencies { get; } /// /// Called after the ownership value for a foreign key is changed. diff --git a/src/EFCore/Metadata/Conventions/Internal/NonNullableConvention.cs b/src/EFCore/Metadata/Conventions/NonNullableConvention.cs similarity index 71% rename from src/EFCore/Metadata/Conventions/Internal/NonNullableConvention.cs rename to src/EFCore/Metadata/Conventions/NonNullableConvention.cs index d3375da9e5c..37a235c8bd8 100644 --- a/src/EFCore/Metadata/Conventions/Internal/NonNullableConvention.cs +++ b/src/EFCore/Metadata/Conventions/NonNullableConvention.cs @@ -4,8 +4,10 @@ using System; using System.Linq; using System.Reflection; +using JetBrains.Annotations; +using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure; -namespace Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal +namespace Microsoft.EntityFrameworkCore.Metadata.Conventions { /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -18,6 +20,22 @@ public abstract class NonNullableConvention private const string NullableAttributeFullName = "System.Runtime.CompilerServices.NullableAttribute"; private Type _nullableAttrType; private FieldInfo _nullableFlagsFieldInfo; + + /// + /// 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. + /// + protected NonNullableConvention([NotNull] ProviderConventionSetBuilderDependencies dependencies) + { + Dependencies = dependencies; + } + + /// + /// Parameter object containing service dependencies. + /// + protected virtual ProviderConventionSetBuilderDependencies Dependencies { get; } /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -25,7 +43,7 @@ public abstract class NonNullableConvention /// 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. /// - protected virtual bool IsNonNullable(MemberInfo memberInfo) + protected virtual bool IsNonNullable([NotNull] MemberInfo memberInfo) { // For C# 8.0 nullable types, the C# currently synthesizes a NullableAttribute that expresses nullability into assemblies // it produces. If the model is spread across more than one assembly, there will be multiple versions of this attribute, diff --git a/src/EFCore/Metadata/Conventions/Internal/NonNullableNavigationConvention.cs b/src/EFCore/Metadata/Conventions/NonNullableNavigationConvention.cs similarity index 79% rename from src/EFCore/Metadata/Conventions/Internal/NonNullableNavigationConvention.cs rename to src/EFCore/Metadata/Conventions/NonNullableNavigationConvention.cs index d9e623d1d8b..185ecc9554e 100644 --- a/src/EFCore/Metadata/Conventions/Internal/NonNullableNavigationConvention.cs +++ b/src/EFCore/Metadata/Conventions/NonNullableNavigationConvention.cs @@ -6,10 +6,11 @@ using Microsoft.EntityFrameworkCore.Diagnostics; using Microsoft.EntityFrameworkCore.Internal; using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure; using Microsoft.EntityFrameworkCore.Metadata.Internal; using Microsoft.EntityFrameworkCore.Utilities; -namespace Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal +namespace Microsoft.EntityFrameworkCore.Metadata.Conventions { /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -25,19 +26,11 @@ public class NonNullableNavigationConvention : NonNullableConvention, INavigatio /// 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 NonNullableNavigationConvention([NotNull] IDiagnosticsLogger logger) + public NonNullableNavigationConvention([NotNull] ProviderConventionSetBuilderDependencies dependencies) + : base(dependencies) { - Logger = logger; } - /// - /// 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. - /// - protected virtual IDiagnosticsLogger Logger { get; } - /// /// Called after a navigation is added to the entity type. /// @@ -65,7 +58,7 @@ public virtual void ProcessNavigationAdded( { if (IsNonNullable(inverse)) { - Logger.NonNullableReferenceOnBothNavigations(navigation, inverse); + Dependencies.Logger.NonNullableReferenceOnBothNavigations(navigation, inverse); return; } } @@ -85,7 +78,7 @@ public virtual void ProcessNavigationAdded( return; } - Logger.NonNullableOnDependent(newRelationshipBuilder.Metadata.DependentToPrincipal); + Dependencies.Logger.NonNullableOnDependent(newRelationshipBuilder.Metadata.DependentToPrincipal); relationshipBuilder = newRelationshipBuilder; } diff --git a/src/EFCore/Metadata/Conventions/Internal/NonNullableReferencePropertyConvention.cs b/src/EFCore/Metadata/Conventions/NonNullableReferencePropertyConvention.cs similarity index 82% rename from src/EFCore/Metadata/Conventions/Internal/NonNullableReferencePropertyConvention.cs rename to src/EFCore/Metadata/Conventions/NonNullableReferencePropertyConvention.cs index 69d1203d6ae..0601d3725ae 100644 --- a/src/EFCore/Metadata/Conventions/Internal/NonNullableReferencePropertyConvention.cs +++ b/src/EFCore/Metadata/Conventions/NonNullableReferencePropertyConvention.cs @@ -5,9 +5,10 @@ using JetBrains.Annotations; using Microsoft.EntityFrameworkCore.Diagnostics; using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure; using Microsoft.EntityFrameworkCore.Metadata.Internal; -namespace Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal +namespace Microsoft.EntityFrameworkCore.Metadata.Conventions { /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -24,19 +25,11 @@ public class NonNullableReferencePropertyConvention : NonNullableConvention, /// 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 NonNullableReferencePropertyConvention([NotNull] IDiagnosticsLogger logger) + public NonNullableReferencePropertyConvention([NotNull] ProviderConventionSetBuilderDependencies dependencies) + : base(dependencies) { - Logger = logger; } - /// - /// 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. - /// - protected virtual IDiagnosticsLogger Logger { get; } - private void Process(IConventionPropertyBuilder propertyBuilder) { // If the model is spread across multiple assemblies, it may contain different NullableAttribute types as diff --git a/src/EFCore/Metadata/Conventions/Internal/NotMappedEntityTypeAttributeConvention.cs b/src/EFCore/Metadata/Conventions/NotMappedEntityTypeAttributeConvention.cs similarity index 92% rename from src/EFCore/Metadata/Conventions/Internal/NotMappedEntityTypeAttributeConvention.cs rename to src/EFCore/Metadata/Conventions/NotMappedEntityTypeAttributeConvention.cs index 40d592e2874..b55e8a68f85 100644 --- a/src/EFCore/Metadata/Conventions/Internal/NotMappedEntityTypeAttributeConvention.cs +++ b/src/EFCore/Metadata/Conventions/NotMappedEntityTypeAttributeConvention.cs @@ -3,11 +3,11 @@ using System.ComponentModel.DataAnnotations.Schema; using JetBrains.Annotations; -using Microsoft.EntityFrameworkCore.Diagnostics; using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure; using Microsoft.EntityFrameworkCore.Utilities; -namespace Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal +namespace Microsoft.EntityFrameworkCore.Metadata.Conventions { /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -23,8 +23,8 @@ public class NotMappedEntityTypeAttributeConvention : EntityTypeAttributeConvent /// 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 NotMappedEntityTypeAttributeConvention([NotNull] IDiagnosticsLogger logger) - : base(logger) + public NotMappedEntityTypeAttributeConvention([NotNull] ProviderConventionSetBuilderDependencies dependencies) + : base(dependencies) { } diff --git a/src/EFCore/Metadata/Conventions/Internal/NotMappedMemberAttributeConvention.cs b/src/EFCore/Metadata/Conventions/NotMappedMemberAttributeConvention.cs similarity index 77% rename from src/EFCore/Metadata/Conventions/Internal/NotMappedMemberAttributeConvention.cs rename to src/EFCore/Metadata/Conventions/NotMappedMemberAttributeConvention.cs index deb5ff75a32..fc843e6f21f 100644 --- a/src/EFCore/Metadata/Conventions/Internal/NotMappedMemberAttributeConvention.cs +++ b/src/EFCore/Metadata/Conventions/NotMappedMemberAttributeConvention.cs @@ -6,12 +6,12 @@ using System.Linq; using System.Reflection; using JetBrains.Annotations; -using Microsoft.EntityFrameworkCore.Diagnostics; using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure; using Microsoft.EntityFrameworkCore.Metadata.Internal; using Microsoft.EntityFrameworkCore.Utilities; -namespace Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal +namespace Microsoft.EntityFrameworkCore.Metadata.Conventions { /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -27,18 +27,15 @@ public class NotMappedMemberAttributeConvention : IEntityTypeAddedConvention /// 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 NotMappedMemberAttributeConvention([NotNull] IDiagnosticsLogger logger) + public NotMappedMemberAttributeConvention([NotNull] ProviderConventionSetBuilderDependencies dependencies) { - Logger = logger; + Dependencies = dependencies; } /// - /// 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. + /// Parameter object containing service dependencies. /// - protected virtual IDiagnosticsLogger Logger { get; } + protected virtual ProviderConventionSetBuilderDependencies Dependencies { get; } /// /// Called after an entity type is added to the model. diff --git a/src/EFCore/Metadata/Conventions/Internal/OwnedEntityTypeAttributeConvention.cs b/src/EFCore/Metadata/Conventions/OwnedEntityTypeAttributeConvention.cs similarity index 89% rename from src/EFCore/Metadata/Conventions/Internal/OwnedEntityTypeAttributeConvention.cs rename to src/EFCore/Metadata/Conventions/OwnedEntityTypeAttributeConvention.cs index eb8241c6f60..56e14fc1e6e 100644 --- a/src/EFCore/Metadata/Conventions/Internal/OwnedEntityTypeAttributeConvention.cs +++ b/src/EFCore/Metadata/Conventions/OwnedEntityTypeAttributeConvention.cs @@ -2,11 +2,11 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using JetBrains.Annotations; -using Microsoft.EntityFrameworkCore.Diagnostics; using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure; using Microsoft.EntityFrameworkCore.Metadata.Internal; -namespace Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal +namespace Microsoft.EntityFrameworkCore.Metadata.Conventions { /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -22,8 +22,8 @@ public class OwnedEntityTypeAttributeConvention : EntityTypeAttributeConvention< /// 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 OwnedEntityTypeAttributeConvention([NotNull] IDiagnosticsLogger logger) - : base(logger) + public OwnedEntityTypeAttributeConvention([NotNull] ProviderConventionSetBuilderDependencies dependencies) + : base(dependencies) { } diff --git a/src/EFCore/Metadata/Conventions/Internal/OwnedTypesConvention.cs b/src/EFCore/Metadata/Conventions/OwnedTypesConvention.cs similarity index 77% rename from src/EFCore/Metadata/Conventions/Internal/OwnedTypesConvention.cs rename to src/EFCore/Metadata/Conventions/OwnedTypesConvention.cs index 04e5f2e41a7..f4045340d0b 100644 --- a/src/EFCore/Metadata/Conventions/Internal/OwnedTypesConvention.cs +++ b/src/EFCore/Metadata/Conventions/OwnedTypesConvention.cs @@ -3,11 +3,11 @@ using System.Linq; using JetBrains.Annotations; -using Microsoft.EntityFrameworkCore.Diagnostics; using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure; using Microsoft.EntityFrameworkCore.Metadata.Internal; -namespace Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal +namespace Microsoft.EntityFrameworkCore.Metadata.Conventions { /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -23,18 +23,15 @@ public class OwnedTypesConvention : IEntityTypeRemovedConvention /// 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 OwnedTypesConvention([NotNull] IDiagnosticsLogger logger) + public OwnedTypesConvention([NotNull] ProviderConventionSetBuilderDependencies dependencies) { - Logger = logger; + Dependencies = dependencies; } /// - /// 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. + /// Parameter object containing service dependencies. /// - protected virtual IDiagnosticsLogger Logger { get; } + protected virtual ProviderConventionSetBuilderDependencies Dependencies { get; } /// /// Called after an entity type is removed from the model. diff --git a/src/EFCore/Metadata/Conventions/Internal/PropertyAttributeConvention.cs b/src/EFCore/Metadata/Conventions/PropertyAttributeConvention.cs similarity index 85% rename from src/EFCore/Metadata/Conventions/Internal/PropertyAttributeConvention.cs rename to src/EFCore/Metadata/Conventions/PropertyAttributeConvention.cs index 03d3036568a..67929bcce7d 100644 --- a/src/EFCore/Metadata/Conventions/Internal/PropertyAttributeConvention.cs +++ b/src/EFCore/Metadata/Conventions/PropertyAttributeConvention.cs @@ -4,12 +4,13 @@ using System; using System.Reflection; using JetBrains.Annotations; -using Microsoft.EntityFrameworkCore.Diagnostics; using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal; using Microsoft.EntityFrameworkCore.Metadata.Internal; using Microsoft.EntityFrameworkCore.Utilities; -namespace Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal +namespace Microsoft.EntityFrameworkCore.Metadata.Conventions { /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -26,18 +27,15 @@ public abstract class PropertyAttributeConvention : IPropertyAddedCo /// 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. /// - protected PropertyAttributeConvention([NotNull] IDiagnosticsLogger logger) + protected PropertyAttributeConvention([NotNull] ProviderConventionSetBuilderDependencies dependencies) { - Logger = logger; + Dependencies = dependencies; } /// - /// 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. + /// Parameter object containing service dependencies. /// - protected virtual IDiagnosticsLogger Logger { get; } + protected virtual ProviderConventionSetBuilderDependencies Dependencies { get; } /// /// Called after a property is added to the entity type. diff --git a/src/EFCore/Metadata/Conventions/Internal/PropertyDiscoveryConvention.cs b/src/EFCore/Metadata/Conventions/PropertyDiscoveryConvention.cs similarity index 79% rename from src/EFCore/Metadata/Conventions/Internal/PropertyDiscoveryConvention.cs rename to src/EFCore/Metadata/Conventions/PropertyDiscoveryConvention.cs index ee0a746e7eb..dc6d333c8ca 100644 --- a/src/EFCore/Metadata/Conventions/Internal/PropertyDiscoveryConvention.cs +++ b/src/EFCore/Metadata/Conventions/PropertyDiscoveryConvention.cs @@ -3,13 +3,12 @@ using System.Reflection; using JetBrains.Annotations; -using Microsoft.EntityFrameworkCore.Diagnostics; using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure; using Microsoft.EntityFrameworkCore.Metadata.Internal; -using Microsoft.EntityFrameworkCore.Storage; using Microsoft.EntityFrameworkCore.Utilities; -namespace Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal +namespace Microsoft.EntityFrameworkCore.Metadata.Conventions { /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -19,29 +18,21 @@ namespace Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal /// public class PropertyDiscoveryConvention : IEntityTypeAddedConvention, IEntityTypeBaseTypeChangedConvention { - private readonly ITypeMappingSource _typeMappingSource; - /// /// 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 PropertyDiscoveryConvention( - [NotNull] ITypeMappingSource typeMappingSource, - [NotNull] IDiagnosticsLogger logger) + public PropertyDiscoveryConvention([NotNull] ProviderConventionSetBuilderDependencies dependencies) { - _typeMappingSource = typeMappingSource; - Logger = logger; + Dependencies = dependencies; } /// - /// 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. + /// Parameter object containing service dependencies. /// - protected virtual IDiagnosticsLogger Logger { get; } + protected virtual ProviderConventionSetBuilderDependencies Dependencies { get; } /// /// Called after an entity type is added to the model. @@ -102,7 +93,7 @@ protected virtual bool IsCandidatePrimitiveProperty([NotNull] PropertyInfo prope Check.NotNull(propertyInfo, nameof(propertyInfo)); return propertyInfo.IsCandidateProperty() - && _typeMappingSource.FindMapping(propertyInfo) != null; + && Dependencies.TypeMappingSource.FindMapping(propertyInfo) != null; } } } diff --git a/src/EFCore/Metadata/Conventions/Internal/RelationshipDiscoveryConvention.cs b/src/EFCore/Metadata/Conventions/RelationshipDiscoveryConvention.cs similarity index 93% rename from src/EFCore/Metadata/Conventions/Internal/RelationshipDiscoveryConvention.cs rename to src/EFCore/Metadata/Conventions/RelationshipDiscoveryConvention.cs index 91c57c2c1b4..879c7d782bd 100644 --- a/src/EFCore/Metadata/Conventions/Internal/RelationshipDiscoveryConvention.cs +++ b/src/EFCore/Metadata/Conventions/RelationshipDiscoveryConvention.cs @@ -10,10 +10,10 @@ using JetBrains.Annotations; using Microsoft.EntityFrameworkCore.Diagnostics; using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure; using Microsoft.EntityFrameworkCore.Metadata.Internal; -using Microsoft.EntityFrameworkCore.Utilities; -namespace Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal +namespace Microsoft.EntityFrameworkCore.Metadata.Conventions { /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -29,48 +29,21 @@ public class RelationshipDiscoveryConvention : INavigationAddedConvention, IForeignKeyOwnershipChangedConvention { - private readonly IMemberClassifier _memberClassifier; - /// /// 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 RelationshipDiscoveryConvention( - [NotNull] IMemberClassifier memberClassifier, - [NotNull] IDiagnosticsLogger logger) + public RelationshipDiscoveryConvention([NotNull] ProviderConventionSetBuilderDependencies dependencies) { - Check.NotNull(memberClassifier, nameof(memberClassifier)); - Check.NotNull(logger, nameof(logger)); - - _memberClassifier = memberClassifier; - Logger = logger; + Dependencies = dependencies; } /// - /// 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. + /// Parameter object containing service dependencies. /// - protected virtual IDiagnosticsLogger Logger { get; } - - /// - /// 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 const string NavigationCandidatesAnnotationName = "RelationshipDiscoveryConvention:NavigationCandidates"; - - /// - /// 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 const string AmbiguousNavigationsAnnotationName = "RelationshipDiscoveryConvention:AmbiguousNavigations"; + protected virtual ProviderConventionSetBuilderDependencies Dependencies { get; } private void DiscoverRelationships(IConventionEntityTypeBuilder entityTypeBuilder, IConventionContext context) { @@ -602,7 +575,7 @@ private void CreateRelationships( { if (!isAmbiguousOnBase) { - Logger.MultipleNavigationProperties( + Dependencies.Logger.MultipleNavigationProperties( relationshipCandidate.NavigationProperties.Count == 0 ? new[] { @@ -850,29 +823,23 @@ public virtual void ProcessNavigationRemoved( } } - private bool Process( + private void Process( IConventionEntityType entityType, string navigationName, MemberInfo memberInfo, IConventionContext context) { DiscoverRelationships(entityType.Builder, context); - if (entityType.FindNavigation(navigationName) != null) - { - return false; - } - - if (IsAmbiguous(entityType, memberInfo)) + if (entityType.FindNavigation(navigationName) != null + || IsAmbiguous(entityType, memberInfo)) { - return true; + return; } foreach (var derivedEntityType in entityType.GetDirectlyDerivedTypes()) { Process(derivedEntityType, navigationName, memberInfo, context); } - - return true; } [ContractAnnotation("memberInfo:null => false")] @@ -981,18 +948,12 @@ public virtual void ProcessForeignKeyOwnershipChanged( IConventionContext context) => DiscoverRelationships(relationshipBuilder.Metadata.DeclaringEntityType.Builder, 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. - /// - public virtual Type FindCandidateNavigationPropertyType([NotNull] PropertyInfo propertyInfo) - => _memberClassifier.FindCandidateNavigationPropertyType(propertyInfo); + private Type FindCandidateNavigationPropertyType([NotNull] PropertyInfo propertyInfo) + => Dependencies.MemberClassifier.FindCandidateNavigationPropertyType(propertyInfo); private ImmutableSortedDictionary GetNavigationCandidates(IConventionEntityType entityType) { - if (entityType.FindAnnotation(NavigationCandidatesAnnotationName)?.Value + if (entityType.FindAnnotation(CoreAnnotationNames.NavigationCandidates)?.Value is ImmutableSortedDictionary navigationCandidates) { return navigationCandidates; @@ -1019,7 +980,7 @@ private ImmutableSortedDictionary GetNavigationCandidates(IC private static void SetNavigationCandidates( IConventionEntityTypeBuilder entityTypeBuilder, ImmutableSortedDictionary navigationCandidates) - => entityTypeBuilder.HasAnnotation(NavigationCandidatesAnnotationName, navigationCandidates); + => entityTypeBuilder.HasAnnotation(CoreAnnotationNames.NavigationCandidates, navigationCandidates); private static bool IsCandidateUnusedOwnedType(IConventionEntityType entityType) => entityType.HasDefiningNavigation() && !entityType.GetForeignKeys().Any(); @@ -1062,7 +1023,7 @@ private static bool HasDeclaredAmbiguousNavigationsTo(IConventionEntityType sour } private static ImmutableSortedDictionary GetAmbiguousNavigations(IConventionEntityType entityType) - => entityType.FindAnnotation(AmbiguousNavigationsAnnotationName)?.Value + => entityType.FindAnnotation(CoreAnnotationNames.AmbiguousNavigations)?.Value as ImmutableSortedDictionary; private static void AddAmbiguous( @@ -1116,7 +1077,7 @@ private static bool RemoveAmbiguous(IConventionEntityType entityType, Type targe private static void SetAmbiguousNavigations( IConventionEntityTypeBuilder entityTypeBuilder, ImmutableSortedDictionary ambiguousNavigations) - => entityTypeBuilder.HasAnnotation(AmbiguousNavigationsAnnotationName, ambiguousNavigations); + => entityTypeBuilder.HasAnnotation(CoreAnnotationNames.AmbiguousNavigations, ambiguousNavigations); private class MemberInfoNameComparer : IComparer { diff --git a/src/EFCore/Metadata/Conventions/Internal/RequiredNavigationAttributeConvention.cs b/src/EFCore/Metadata/Conventions/RequiredNavigationAttributeConvention.cs similarity index 88% rename from src/EFCore/Metadata/Conventions/Internal/RequiredNavigationAttributeConvention.cs rename to src/EFCore/Metadata/Conventions/RequiredNavigationAttributeConvention.cs index 784348fa2f1..4eaae6babae 100644 --- a/src/EFCore/Metadata/Conventions/Internal/RequiredNavigationAttributeConvention.cs +++ b/src/EFCore/Metadata/Conventions/RequiredNavigationAttributeConvention.cs @@ -6,9 +6,10 @@ using JetBrains.Annotations; using Microsoft.EntityFrameworkCore.Diagnostics; using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure; using Microsoft.EntityFrameworkCore.Utilities; -namespace Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal +namespace Microsoft.EntityFrameworkCore.Metadata.Conventions { /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -24,8 +25,8 @@ public class RequiredNavigationAttributeConvention : NavigationAttributeNavigati /// 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 RequiredNavigationAttributeConvention([NotNull] IDiagnosticsLogger logger) - : base(logger) + public RequiredNavigationAttributeConvention([NotNull] ProviderConventionSetBuilderDependencies dependencies) + : base(dependencies) { } @@ -58,7 +59,7 @@ public override void ProcessNavigationAdded( var attributes = GetAttributes(inverse.DeclaringEntityType, inverse); if (attributes.Any()) { - Logger.RequiredAttributeOnBothNavigations(navigation, inverse); + Dependencies.Logger.RequiredAttributeOnBothNavigations(navigation, inverse); return; } } @@ -78,7 +79,7 @@ public override void ProcessNavigationAdded( return; } - Logger.RequiredAttributeOnDependent(newRelationshipBuilder.Metadata.DependentToPrincipal); + Dependencies.Logger.RequiredAttributeOnDependent(newRelationshipBuilder.Metadata.DependentToPrincipal); relationshipBuilder = newRelationshipBuilder; } diff --git a/src/EFCore/Metadata/Conventions/Internal/RequiredPropertyAttributeConvention.cs b/src/EFCore/Metadata/Conventions/RequiredPropertyAttributeConvention.cs similarity index 89% rename from src/EFCore/Metadata/Conventions/Internal/RequiredPropertyAttributeConvention.cs rename to src/EFCore/Metadata/Conventions/RequiredPropertyAttributeConvention.cs index 951d4545a7b..0cb7f06480a 100644 --- a/src/EFCore/Metadata/Conventions/Internal/RequiredPropertyAttributeConvention.cs +++ b/src/EFCore/Metadata/Conventions/RequiredPropertyAttributeConvention.cs @@ -4,11 +4,11 @@ using System.ComponentModel.DataAnnotations; using System.Reflection; using JetBrains.Annotations; -using Microsoft.EntityFrameworkCore.Diagnostics; using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure; using Microsoft.EntityFrameworkCore.Utilities; -namespace Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal +namespace Microsoft.EntityFrameworkCore.Metadata.Conventions { /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -24,8 +24,8 @@ public class RequiredPropertyAttributeConvention : PropertyAttributeConvention - public RequiredPropertyAttributeConvention([NotNull] IDiagnosticsLogger logger) - : base(logger) + public RequiredPropertyAttributeConvention([NotNull] ProviderConventionSetBuilderDependencies dependencies) + : base(dependencies) { } diff --git a/src/EFCore/Metadata/Conventions/Internal/ServicePropertyDiscoveryConvention.cs b/src/EFCore/Metadata/Conventions/ServicePropertyDiscoveryConvention.cs similarity index 83% rename from src/EFCore/Metadata/Conventions/Internal/ServicePropertyDiscoveryConvention.cs rename to src/EFCore/Metadata/Conventions/ServicePropertyDiscoveryConvention.cs index dac9cde9f19..ed15a02c18f 100644 --- a/src/EFCore/Metadata/Conventions/Internal/ServicePropertyDiscoveryConvention.cs +++ b/src/EFCore/Metadata/Conventions/ServicePropertyDiscoveryConvention.cs @@ -10,11 +10,10 @@ using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Internal; using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure; using Microsoft.EntityFrameworkCore.Metadata.Internal; -using Microsoft.EntityFrameworkCore.Storage; -using Microsoft.EntityFrameworkCore.Utilities; -namespace Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal +namespace Microsoft.EntityFrameworkCore.Metadata.Conventions { /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -28,37 +27,21 @@ public class ServicePropertyDiscoveryConvention : IEntityTypeMemberIgnoredConvention, IModelFinalizedConvention { - private readonly ITypeMappingSource _typeMappingSource; - private readonly IParameterBindingFactories _parameterBindingFactories; - - private const string DuplicateServicePropertiesAnnotationName = "RelationshipDiscoveryConvention:DuplicateServiceProperties"; - /// /// 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 ServicePropertyDiscoveryConvention( - [NotNull] ITypeMappingSource typeMappingSource, - [NotNull] IParameterBindingFactories parameterBindingFactories, - [NotNull] IDiagnosticsLogger logger) + public ServicePropertyDiscoveryConvention([NotNull] ProviderConventionSetBuilderDependencies dependencies) { - Check.NotNull(typeMappingSource, nameof(typeMappingSource)); - Check.NotNull(parameterBindingFactories, nameof(parameterBindingFactories)); - - _typeMappingSource = typeMappingSource; - _parameterBindingFactories = parameterBindingFactories; - Logger = logger; + Dependencies = dependencies; } /// - /// 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. + /// Parameter object containing service dependencies. /// - protected virtual IDiagnosticsLogger Logger { get; } + protected virtual ProviderConventionSetBuilderDependencies Dependencies { get; } /// /// Called after an entity type is added to the model. @@ -108,12 +91,12 @@ private void Process(IConventionEntityTypeBuilder entityTypeBuilder) || entityType.FindNavigation(propertyInfo) != null || !propertyInfo.IsCandidateProperty(publicOnly: false) || (propertyInfo.IsCandidateProperty() - && _typeMappingSource.FindMapping(propertyInfo) != null)) + && Dependencies.TypeMappingSource.FindMapping(propertyInfo) != null)) { continue; } - var factory = _parameterBindingFactories.FindFactory(propertyInfo.PropertyType, propertyInfo.GetSimpleMemberName()); + var factory = Dependencies.ParameterBindingFactories.FindFactory(propertyInfo.PropertyType, propertyInfo.GetSimpleMemberName()); if (factory == null) { continue; @@ -177,7 +160,7 @@ public virtual void ProcessEntityTypeMemberIgnored( var otherMember = duplicateServiceProperties.First(); var otherName = otherMember.GetSimpleMemberName(); - var factory = _parameterBindingFactories.FindFactory(type, otherName); + var factory = Dependencies.ParameterBindingFactories.FindFactory(type, otherName); entityType.Builder.ServiceProperty(otherMember)?.HasParameterBinding( (ServiceParameterBinding)factory.Bind(entityType, type, otherName)); duplicateMap.Remove(type); @@ -241,12 +224,12 @@ private static void AddDuplicateServiceProperty(IConventionEntityTypeBuilder ent } private static Dictionary> GetDuplicateServiceProperties(IConventionEntityType entityType) - => entityType.FindAnnotation(DuplicateServicePropertiesAnnotationName)?.Value + => entityType.FindAnnotation(CoreAnnotationNames.DuplicateServiceProperties)?.Value as Dictionary>; private static void SetDuplicateServiceProperties( IConventionEntityTypeBuilder entityTypeBuilder, Dictionary> duplicateServiceProperties) - => entityTypeBuilder.HasAnnotation(DuplicateServicePropertiesAnnotationName, duplicateServiceProperties); + => entityTypeBuilder.HasAnnotation(CoreAnnotationNames.DuplicateServiceProperties, duplicateServiceProperties); } } diff --git a/src/EFCore/Metadata/Conventions/Internal/StringLengthAttributeConvention.cs b/src/EFCore/Metadata/Conventions/StringLengthAttributeConvention.cs similarity index 89% rename from src/EFCore/Metadata/Conventions/Internal/StringLengthAttributeConvention.cs rename to src/EFCore/Metadata/Conventions/StringLengthAttributeConvention.cs index d4ce484bb33..8a9fef6e59d 100644 --- a/src/EFCore/Metadata/Conventions/Internal/StringLengthAttributeConvention.cs +++ b/src/EFCore/Metadata/Conventions/StringLengthAttributeConvention.cs @@ -4,11 +4,11 @@ using System.ComponentModel.DataAnnotations; using System.Reflection; using JetBrains.Annotations; -using Microsoft.EntityFrameworkCore.Diagnostics; using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure; using Microsoft.EntityFrameworkCore.Utilities; -namespace Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal +namespace Microsoft.EntityFrameworkCore.Metadata.Conventions { /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -24,8 +24,8 @@ public class StringLengthAttributeConvention : PropertyAttributeConvention - public StringLengthAttributeConvention([NotNull] IDiagnosticsLogger logger) - : base(logger) + public StringLengthAttributeConvention([NotNull] ProviderConventionSetBuilderDependencies dependencies) + : base(dependencies) { } diff --git a/src/EFCore/Metadata/Conventions/Internal/TimestampAttributeConvention.cs b/src/EFCore/Metadata/Conventions/TimestampAttributeConvention.cs similarity index 90% rename from src/EFCore/Metadata/Conventions/Internal/TimestampAttributeConvention.cs rename to src/EFCore/Metadata/Conventions/TimestampAttributeConvention.cs index e6a6999dcc8..bd90c720f10 100644 --- a/src/EFCore/Metadata/Conventions/Internal/TimestampAttributeConvention.cs +++ b/src/EFCore/Metadata/Conventions/TimestampAttributeConvention.cs @@ -4,11 +4,11 @@ using System.ComponentModel.DataAnnotations; using System.Reflection; using JetBrains.Annotations; -using Microsoft.EntityFrameworkCore.Diagnostics; using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure; using Microsoft.EntityFrameworkCore.Utilities; -namespace Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal +namespace Microsoft.EntityFrameworkCore.Metadata.Conventions { /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -24,8 +24,8 @@ public class TimestampAttributeConvention : PropertyAttributeConvention - public TimestampAttributeConvention([NotNull] IDiagnosticsLogger logger) - : base(logger) + public TimestampAttributeConvention([NotNull] ProviderConventionSetBuilderDependencies dependencies) + : base(dependencies) { } diff --git a/src/EFCore/Metadata/Conventions/Internal/TypeMappingConvention.cs b/src/EFCore/Metadata/Conventions/TypeMappingConvention.cs similarity index 66% rename from src/EFCore/Metadata/Conventions/Internal/TypeMappingConvention.cs rename to src/EFCore/Metadata/Conventions/TypeMappingConvention.cs index c247b3282f1..ddbb5e4f01b 100644 --- a/src/EFCore/Metadata/Conventions/Internal/TypeMappingConvention.cs +++ b/src/EFCore/Metadata/Conventions/TypeMappingConvention.cs @@ -3,12 +3,11 @@ using System.Linq; using JetBrains.Annotations; -using Microsoft.EntityFrameworkCore.Diagnostics; using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure; using Microsoft.EntityFrameworkCore.Metadata.Internal; -using Microsoft.EntityFrameworkCore.Storage; -namespace Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal +namespace Microsoft.EntityFrameworkCore.Metadata.Conventions { /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -18,29 +17,21 @@ namespace Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal /// public class TypeMappingConvention : IModelFinalizedConvention { - private readonly ITypeMappingSource _typeMappingSource; - /// /// 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 TypeMappingConvention( - [NotNull] ITypeMappingSource typeMappingSource, - [NotNull] IDiagnosticsLogger logger) + public TypeMappingConvention([NotNull] ProviderConventionSetBuilderDependencies dependencies) { - _typeMappingSource = typeMappingSource; - Logger = logger; + Dependencies = dependencies; } /// - /// 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. + /// Parameter object containing service dependencies. /// - protected virtual IDiagnosticsLogger Logger { get; } + protected virtual ProviderConventionSetBuilderDependencies Dependencies { get; } /// /// Called after a model is finalized. @@ -53,7 +44,7 @@ public virtual void ProcessModelFinalized(IConventionModelBuilder modelBuilder, { property.Builder.HasAnnotation( CoreAnnotationNames.TypeMapping, - _typeMappingSource.FindMapping(property)); + Dependencies.TypeMappingSource.FindMapping(property)); } } } diff --git a/src/EFCore/Metadata/Conventions/Internal/ValidatingConvention.cs b/src/EFCore/Metadata/Conventions/ValidatingConvention.cs similarity index 74% rename from src/EFCore/Metadata/Conventions/Internal/ValidatingConvention.cs rename to src/EFCore/Metadata/Conventions/ValidatingConvention.cs index 51c51eb245f..932be1658fb 100644 --- a/src/EFCore/Metadata/Conventions/Internal/ValidatingConvention.cs +++ b/src/EFCore/Metadata/Conventions/ValidatingConvention.cs @@ -2,11 +2,10 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using JetBrains.Annotations; -using Microsoft.EntityFrameworkCore.Diagnostics; -using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure; -namespace Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal +namespace Microsoft.EntityFrameworkCore.Metadata.Conventions { /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -16,27 +15,28 @@ namespace Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal /// public class ValidatingConvention : IModelFinalizedConvention { - private readonly IModelValidator _validator; - private readonly IDiagnosticsLogger _logger; - /// /// 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 ValidatingConvention([NotNull] IModelValidator validator, [NotNull] IDiagnosticsLogger logger) + public ValidatingConvention([NotNull] ProviderConventionSetBuilderDependencies dependencies) { - _validator = validator; - _logger = logger; + Dependencies = dependencies; } + /// + /// Parameter object containing service dependencies. + /// + protected virtual ProviderConventionSetBuilderDependencies Dependencies { get; } + /// /// Called after a model is finalized. /// /// The builder for the model. /// Additional information associated with convention execution. public virtual void ProcessModelFinalized(IConventionModelBuilder modelBuilder, IConventionContext context) - => _validator.Validate(modelBuilder.Metadata, _logger); + => Dependencies.ModelValidator.Validate(modelBuilder.Metadata, Dependencies.ValidationLogger); } } diff --git a/src/EFCore/Metadata/Conventions/Internal/ValueGeneratorConvention.cs b/src/EFCore/Metadata/Conventions/ValueGeneratorConvention.cs similarity index 89% rename from src/EFCore/Metadata/Conventions/Internal/ValueGeneratorConvention.cs rename to src/EFCore/Metadata/Conventions/ValueGeneratorConvention.cs index 7c0b1dcb810..82951fc3eae 100644 --- a/src/EFCore/Metadata/Conventions/Internal/ValueGeneratorConvention.cs +++ b/src/EFCore/Metadata/Conventions/ValueGeneratorConvention.cs @@ -5,10 +5,10 @@ using System.Collections.Generic; using System.Linq; using JetBrains.Annotations; -using Microsoft.EntityFrameworkCore.Diagnostics; using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure; -namespace Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal +namespace Microsoft.EntityFrameworkCore.Metadata.Conventions { /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -29,18 +29,15 @@ public class ValueGeneratorConvention : /// 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 ValueGeneratorConvention([NotNull] IDiagnosticsLogger logger) + public ValueGeneratorConvention([NotNull] ProviderConventionSetBuilderDependencies dependencies) { - Logger = logger; + Dependencies = dependencies; } /// - /// 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. + /// Parameter object containing service dependencies. /// - protected virtual IDiagnosticsLogger Logger { get; } + protected virtual ProviderConventionSetBuilderDependencies Dependencies { get; } /// /// Called after a foreign key is added to the entity type. @@ -176,7 +173,15 @@ public virtual void ProcessEntityTypeBaseTypeChanged( /// /// The property. /// The store value generation strategy to set for the given property. - public virtual ValueGenerated? GetValueGenerated([NotNull] IConventionProperty property) + protected virtual ValueGenerated? GetValueGenerated([NotNull] IConventionProperty property) + => GetValueGenerated((IProperty)property); + + /// + /// Returns the store value generation strategy to set for the given property. + /// + /// The property. + /// The store value generation strategy to set for the given property. + public static ValueGenerated? GetValueGenerated([NotNull] IProperty property) => !property.IsForeignKey() && property.FindContainingPrimaryKey()?.Properties.Count(p => !p.IsForeignKey()) == 1 && CanBeGenerated(property) @@ -189,7 +194,7 @@ public virtual void ProcessEntityTypeBaseTypeChanged( /// /// The key property that might be store generated. /// A value indicating whether the specified property should have the value generated by the store. - private static bool CanBeGenerated(IConventionProperty property) + private static bool CanBeGenerated(IProperty property) { var propertyType = property.ClrType.UnwrapNullableType(); return (propertyType.IsInteger() diff --git a/src/EFCore/Metadata/Internal/CoreAnnotationNames.cs b/src/EFCore/Metadata/Internal/CoreAnnotationNames.cs index 293ccaf746a..956e69ace9d 100644 --- a/src/EFCore/Metadata/Internal/CoreAnnotationNames.cs +++ b/src/EFCore/Metadata/Internal/CoreAnnotationNames.cs @@ -1,6 +1,8 @@ // 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 Microsoft.EntityFrameworkCore.Infrastructure; + namespace Microsoft.EntityFrameworkCore.Metadata.Internal { /// @@ -186,5 +188,37 @@ public static class CoreAnnotationNames /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public const string ProviderClrType = "ProviderClrType"; + + /// + /// 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 const string InverseNavigations = "InversePropertyAttributeConvention:InverseNavigations"; + + /// + /// 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 const string NavigationCandidates = "RelationshipDiscoveryConvention:NavigationCandidates"; + + /// + /// 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 const string AmbiguousNavigations = "RelationshipDiscoveryConvention:AmbiguousNavigations"; + + /// + /// 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 const string DuplicateServiceProperties = "ServicePropertyDiscoveryConvention:DuplicateServiceProperties"; } } diff --git a/src/EFCore/Metadata/Internal/InternalModelBuilder.cs b/src/EFCore/Metadata/Internal/InternalModelBuilder.cs index a4b16a8a198..553deeb5863 100644 --- a/src/EFCore/Metadata/Internal/InternalModelBuilder.cs +++ b/src/EFCore/Metadata/Internal/InternalModelBuilder.cs @@ -72,39 +72,36 @@ private InternalEntityTypeBuilder Entity( ? Metadata.FindEntityType(type.Name) : Metadata.FindEntityType(clrType); - using (Metadata.ConventionDispatcher.DelayConventions()) + if (shouldBeOwned == false + && (ShouldBeOwnedType(type) + || entityType != null && entityType.IsOwned())) { - if (shouldBeOwned == false - && (ShouldBeOwnedType(type) - || entityType != null && entityType.IsOwned())) - { - throw new InvalidOperationException( - CoreStrings.ClashingOwnedEntityType( - clrType == null ? type.Name : clrType.ShortDisplayName())); - } - - if (shouldBeOwned == true - && entityType != null - && !entityType.IsOwned() - && configurationSource == ConfigurationSource.Explicit - && entityType.GetConfigurationSource() == ConfigurationSource.Explicit) - { - throw new InvalidOperationException(CoreStrings.ClashingNonOwnedEntityType(entityType.DisplayName())); - } + throw new InvalidOperationException( + CoreStrings.ClashingOwnedEntityType( + clrType == null ? type.Name : clrType.ShortDisplayName())); + } - if (entityType != null) - { - entityType.UpdateConfigurationSource(configurationSource); - return entityType.Builder; - } + if (shouldBeOwned == true + && entityType != null + && !entityType.IsOwned() + && configurationSource == ConfigurationSource.Explicit + && entityType.GetConfigurationSource() == ConfigurationSource.Explicit) + { + throw new InvalidOperationException(CoreStrings.ClashingNonOwnedEntityType(entityType.DisplayName())); + } - Metadata.RemoveIgnored(type.Name); - entityType = clrType == null - ? Metadata.AddEntityType(type.Name, configurationSource) - : Metadata.AddEntityType(clrType, configurationSource); + if (entityType != null) + { + entityType.UpdateConfigurationSource(configurationSource); + return entityType.Builder; } - return entityType.Builder; + Metadata.RemoveIgnored(type.Name); + entityType = clrType == null + ? Metadata.AddEntityType(type.Name, configurationSource) + : Metadata.AddEntityType(clrType, configurationSource); + + return entityType?.Builder; } /// diff --git a/src/EFCore/Metadata/Internal/InternalRelationshipBuilder.cs b/src/EFCore/Metadata/Internal/InternalRelationshipBuilder.cs index a65727bd807..4487da97a76 100644 --- a/src/EFCore/Metadata/Internal/InternalRelationshipBuilder.cs +++ b/src/EFCore/Metadata/Internal/InternalRelationshipBuilder.cs @@ -3594,7 +3594,10 @@ private enum Resolution } /// - IConventionForeignKey IConventionRelationshipBuilder.Metadata => Metadata; + IConventionForeignKey IConventionRelationshipBuilder.Metadata + { + [DebuggerStepThrough] get => Metadata; + } /// IConventionRelationshipBuilder IConventionRelationshipBuilder.HasEntityTypes( diff --git a/test/EFCore.Design.Tests/EFCore.Design.Tests.csproj b/test/EFCore.Design.Tests/EFCore.Design.Tests.csproj index 2becd9fe2e0..ac7b9c4782a 100644 --- a/test/EFCore.Design.Tests/EFCore.Design.Tests.csproj +++ b/test/EFCore.Design.Tests/EFCore.Design.Tests.csproj @@ -17,9 +17,9 @@ - + diff --git a/test/EFCore.Design.Tests/Migrations/Design/CSharpMigrationsGeneratorTest.cs b/test/EFCore.Design.Tests/Migrations/Design/CSharpMigrationsGeneratorTest.cs index 554e74b4990..736d80394dc 100644 --- a/test/EFCore.Design.Tests/Migrations/Design/CSharpMigrationsGeneratorTest.cs +++ b/test/EFCore.Design.Tests/Migrations/Design/CSharpMigrationsGeneratorTest.cs @@ -59,6 +59,7 @@ public void Test_new_annotations_handled_for_entity_types() CoreAnnotationNames.AfterSaveBehavior, CoreAnnotationNames.ProviderClrType, CoreAnnotationNames.EagerLoaded, + CoreAnnotationNames.DuplicateServiceProperties, RelationalAnnotationNames.ColumnName, RelationalAnnotationNames.ColumnType, RelationalAnnotationNames.DefaultValueSql, @@ -124,14 +125,18 @@ public void Test_new_annotations_handled_for_properties() CoreAnnotationNames.EagerLoaded, CoreAnnotationNames.QueryFilter, CoreAnnotationNames.DefiningQuery, + CoreAnnotationNames.DiscriminatorProperty, + CoreAnnotationNames.DiscriminatorValue, + CoreAnnotationNames.InverseNavigations, + CoreAnnotationNames.NavigationCandidates, + CoreAnnotationNames.AmbiguousNavigations, + CoreAnnotationNames.DuplicateServiceProperties, RelationalAnnotationNames.TableName, RelationalAnnotationNames.Schema, RelationalAnnotationNames.DefaultSchema, RelationalAnnotationNames.Name, RelationalAnnotationNames.SequencePrefix, RelationalAnnotationNames.CheckConstraints, - CoreAnnotationNames.DiscriminatorProperty, - CoreAnnotationNames.DiscriminatorValue, RelationalAnnotationNames.Filter, RelationalAnnotationNames.DbFunction, RelationalAnnotationNames.MaxIdentifierLength diff --git a/test/EFCore.Design.Tests/Scaffolding/Internal/ModelCodeGeneratorTestBase.cs b/test/EFCore.Design.Tests/Scaffolding/Internal/ModelCodeGeneratorTestBase.cs index 894b2688748..af0ded01ea2 100644 --- a/test/EFCore.Design.Tests/Scaffolding/Internal/ModelCodeGeneratorTestBase.cs +++ b/test/EFCore.Design.Tests/Scaffolding/Internal/ModelCodeGeneratorTestBase.cs @@ -5,10 +5,7 @@ using System.Collections.Generic; using System.Linq; using Microsoft.EntityFrameworkCore.Design; -using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Metadata; -using Microsoft.EntityFrameworkCore.Metadata.Conventions; -using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure; using Microsoft.EntityFrameworkCore.Metadata.Internal; using Microsoft.EntityFrameworkCore.SqlServer.Design.Internal; using Microsoft.EntityFrameworkCore.TestUtilities; @@ -18,32 +15,13 @@ namespace Microsoft.EntityFrameworkCore.Scaffolding.Internal { public abstract class ModelCodeGeneratorTestBase { - public static ConventionSet BuildNonValidatingConventionSet() - { - var serviceProvider = new ServiceCollection() - .AddEntityFrameworkSqlServer() - .AddDbContext( - (p, o) => - o.UseSqlServer("Server=.") - .UseInternalServiceProvider(p)) - .BuildServiceProvider(); - - using (var serviceScope = serviceProvider.GetRequiredService().CreateScope()) - { - return serviceScope.ServiceProvider - .GetService() - .GetService() - .CreateConventionSet(); - } - } - protected void Test( Action buildModel, ModelCodeGenerationOptions options, Action assertScaffold, Action assertModel) { - var modelBuilder = new ModelBuilder(BuildNonValidatingConventionSet()); + var modelBuilder = SqlServerTestHelpers.Instance.CreateConventionBuilder(skipValidation: true); modelBuilder.Model.RemoveAnnotation(CoreAnnotationNames.ProductVersion); buildModel(modelBuilder); var _ = modelBuilder.Model.GetEntityTypeErrors(); diff --git a/test/EFCore.Relational.Tests/Metadata/Conventions/Internal/DiscriminatorConventionTest.cs b/test/EFCore.Relational.Tests/Metadata/Conventions/Internal/DiscriminatorConventionTest.cs index 69bd8094d1a..2f8a14429a8 100644 --- a/test/EFCore.Relational.Tests/Metadata/Conventions/Internal/DiscriminatorConventionTest.cs +++ b/test/EFCore.Relational.Tests/Metadata/Conventions/Internal/DiscriminatorConventionTest.cs @@ -4,8 +4,10 @@ using System; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure; using Microsoft.EntityFrameworkCore.Metadata.Internal; using Microsoft.EntityFrameworkCore.TestUtilities; +using Microsoft.Extensions.DependencyInjection; using Xunit; // ReSharper disable UnusedMember.Local @@ -128,7 +130,6 @@ public void Does_nothing_if_explicit_discriminator_is_not_compatible() public void Does_nothing_if_explicit_discriminator_set_on_derived_type() { var entityTypeBuilder = CreateInternalEntityTypeBuilder(); - var logger = new TestLogger(); new EntityTypeBuilder(entityTypeBuilder.Metadata).HasDiscriminator("T", typeof(string)); @@ -154,14 +155,16 @@ public void Does_nothing_if_explicit_discriminator_set_on_derived_type() private void RunConvention(InternalEntityTypeBuilder entityTypeBuilder, EntityType oldBaseType) { - var logger = new TestLogger(); var context = new ConventionContext(entityTypeBuilder.Metadata.Model.ConventionDispatcher); - new DiscriminatorConvention(logger) + new DiscriminatorConvention(CreateDependencies()) .ProcessEntityTypeBaseTypeChanged( entityTypeBuilder, entityTypeBuilder.Metadata.BaseType, oldBaseType, context); Assert.False(context.ShouldStopProcessing()); } + private ProviderConventionSetBuilderDependencies CreateDependencies() + => RelationalTestHelpers.Instance.CreateContextServices().GetRequiredService(); + private class EntityBase { } diff --git a/test/EFCore.Relational.Tests/Metadata/DbFunctionMetadataTests.cs b/test/EFCore.Relational.Tests/Metadata/DbFunctionMetadataTests.cs index 5de1570a874..76b66f18199 100644 --- a/test/EFCore.Relational.Tests/Metadata/DbFunctionMetadataTests.cs +++ b/test/EFCore.Relational.Tests/Metadata/DbFunctionMetadataTests.cs @@ -8,8 +8,9 @@ using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Internal; using Microsoft.EntityFrameworkCore.Metadata.Conventions; -using Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal; +using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure; using Microsoft.EntityFrameworkCore.TestUtilities; +using Microsoft.Extensions.DependencyInjection; using Xunit; // ReSharper disable InconsistentNaming @@ -492,9 +493,15 @@ private ModelBuilder GetModelBuilder() var conventionSet = new ConventionSet(); conventionSet.ModelAnnotationChangedConventions.Add( - new RelationalDbFunctionConvention(new TestLogger())); + new RelationalDbFunctionConvention(CreateDependencies(), CreateRelationalDependencies())); return new ModelBuilder(conventionSet); } + + private ProviderConventionSetBuilderDependencies CreateDependencies() + => RelationalTestHelpers.Instance.CreateContextServices().GetRequiredService(); + + private RelationalConventionSetBuilderDependencies CreateRelationalDependencies() + => RelationalTestHelpers.Instance.CreateContextServices().GetRequiredService(); } } diff --git a/test/EFCore.Relational.Tests/Metadata/RelationalEntityTypeAttributeConventionTest.cs b/test/EFCore.Relational.Tests/Metadata/RelationalEntityTypeAttributeConventionTest.cs index 9a79b2e4628..4ef9c47b432 100644 --- a/test/EFCore.Relational.Tests/Metadata/RelationalEntityTypeAttributeConventionTest.cs +++ b/test/EFCore.Relational.Tests/Metadata/RelationalEntityTypeAttributeConventionTest.cs @@ -4,10 +4,11 @@ using System.ComponentModel.DataAnnotations.Schema; using Microsoft.EntityFrameworkCore.Metadata.Builders; using Microsoft.EntityFrameworkCore.Metadata.Conventions; +using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure; using Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal; using Microsoft.EntityFrameworkCore.Metadata.Internal; -using Microsoft.EntityFrameworkCore.Storage; using Microsoft.EntityFrameworkCore.TestUtilities; +using Microsoft.Extensions.DependencyInjection; using Xunit; // ReSharper disable InconsistentNaming @@ -54,11 +55,11 @@ public void TableAttribute_does_not_override_configuration_from_explicit_source( Assert.Equal("ExplicitName", entityBuilder.Metadata.GetSchema()); } - private static void RunConvention(InternalEntityTypeBuilder entityTypeBuilder) + private void RunConvention(InternalEntityTypeBuilder entityTypeBuilder) { var context = new ConventionContext(entityTypeBuilder.Metadata.Model.ConventionDispatcher); - new RelationalTableAttributeConvention(new TestLogger()) + new RelationalTableAttributeConvention(CreateDependencies(), CreateRelationalDependencies()) .ProcessEntityTypeAdded(entityTypeBuilder, context); } @@ -66,17 +67,19 @@ private InternalEntityTypeBuilder CreateInternalEntityTypeBuilder() { var conventionSet = new ConventionSet(); conventionSet.EntityTypeAddedConventions.Add( - new PropertyDiscoveryConvention( - new TestRelationalTypeMappingSource( - TestServiceFactory.Instance.Create(), - TestServiceFactory.Instance.Create()), - new TestLogger())); + new PropertyDiscoveryConvention(CreateDependencies())); var modelBuilder = new InternalModelBuilder(new Model(conventionSet)); return modelBuilder.Entity(typeof(T), ConfigurationSource.Explicit); } + private ProviderConventionSetBuilderDependencies CreateDependencies() + => RelationalTestHelpers.Instance.CreateContextServices().GetRequiredService(); + + private RelationalConventionSetBuilderDependencies CreateRelationalDependencies() + => RelationalTestHelpers.Instance.CreateContextServices().GetRequiredService(); + protected virtual ModelBuilder CreateConventionalModelBuilder() => RelationalTestHelpers.Instance.CreateConventionBuilder(); diff --git a/test/EFCore.Relational.Tests/Metadata/RelationalPropertyAttributeConventionTest.cs b/test/EFCore.Relational.Tests/Metadata/RelationalPropertyAttributeConventionTest.cs index cc17ea9e801..bd2fe4a3084 100644 --- a/test/EFCore.Relational.Tests/Metadata/RelationalPropertyAttributeConventionTest.cs +++ b/test/EFCore.Relational.Tests/Metadata/RelationalPropertyAttributeConventionTest.cs @@ -4,10 +4,11 @@ using System.ComponentModel.DataAnnotations.Schema; using Microsoft.EntityFrameworkCore.Metadata.Builders; using Microsoft.EntityFrameworkCore.Metadata.Conventions; +using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure; using Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal; using Microsoft.EntityFrameworkCore.Metadata.Internal; -using Microsoft.EntityFrameworkCore.Storage; using Microsoft.EntityFrameworkCore.TestUtilities; +using Microsoft.Extensions.DependencyInjection; using Xunit; // ReSharper disable InconsistentNaming @@ -74,7 +75,7 @@ private void RunConvention(InternalPropertyBuilder propertyBuilder) var context = new ConventionContext( propertyBuilder.Metadata.DeclaringEntityType.Model.ConventionDispatcher); - new RelationalColumnAttributeConvention(new TestLogger()) + new RelationalColumnAttributeConvention(CreateDependencies(), CreateRelationalDependencies()) .ProcessPropertyAdded(propertyBuilder, context); } @@ -82,17 +83,19 @@ private InternalEntityTypeBuilder CreateInternalEntityTypeBuilder() { var conventionSet = new ConventionSet(); conventionSet.EntityTypeAddedConventions.Add( - new PropertyDiscoveryConvention( - new TestRelationalTypeMappingSource( - TestServiceFactory.Instance.Create(), - TestServiceFactory.Instance.Create()), - new TestLogger())); + new PropertyDiscoveryConvention(CreateDependencies())); var modelBuilder = new InternalModelBuilder(new Model(conventionSet)); return modelBuilder.Entity(typeof(T), ConfigurationSource.Explicit); } + private ProviderConventionSetBuilderDependencies CreateDependencies() + => RelationalTestHelpers.Instance.CreateContextServices().GetRequiredService(); + + private RelationalConventionSetBuilderDependencies CreateRelationalDependencies() + => RelationalTestHelpers.Instance.CreateContextServices().GetRequiredService(); + protected virtual ModelBuilder CreateConventionalModelBuilder() => RelationalTestHelpers.Instance.CreateConventionBuilder(); diff --git a/test/EFCore.Relational.Tests/TestUtilities/TestRelationalConventionSetBuilder.cs b/test/EFCore.Relational.Tests/TestUtilities/TestRelationalConventionSetBuilder.cs index ec88c1faa28..1465cf753bb 100644 --- a/test/EFCore.Relational.Tests/TestUtilities/TestRelationalConventionSetBuilder.cs +++ b/test/EFCore.Relational.Tests/TestUtilities/TestRelationalConventionSetBuilder.cs @@ -1,10 +1,7 @@ // 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 Microsoft.EntityFrameworkCore.Metadata.Conventions; using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure; -using Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal; -using Microsoft.EntityFrameworkCore.Storage; namespace Microsoft.EntityFrameworkCore.TestUtilities { @@ -16,25 +13,5 @@ public TestRelationalConventionSetBuilder( : base(dependencies, relationalDependencies) { } - - public static ConventionSet Build() - { - var typeMappingSource = new TestRelationalTypeMappingSource( - TestServiceFactory.Instance.Create(), - TestServiceFactory.Instance.Create()); - - return new TestRelationalConventionSetBuilder( - new ProviderConventionSetBuilderDependencies( - typeMappingSource, - null, - null, - null, - new FakeDiagnosticsLogger(), - null, - null), - new RelationalConventionSetBuilderDependencies( - typeMappingSource)) - .CreateConventionSet(); - } } } diff --git a/test/EFCore.Specification.Tests/DataAnnotationTestBase.cs b/test/EFCore.Specification.Tests/DataAnnotationTestBase.cs index 9f19018b8c3..630bce7df36 100644 --- a/test/EFCore.Specification.Tests/DataAnnotationTestBase.cs +++ b/test/EFCore.Specification.Tests/DataAnnotationTestBase.cs @@ -13,7 +13,6 @@ using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure; -using Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal; using Microsoft.EntityFrameworkCore.Metadata.Internal; using Microsoft.EntityFrameworkCore.Storage; using Microsoft.EntityFrameworkCore.TestUtilities; @@ -45,14 +44,7 @@ protected virtual void UseTransaction(DatabaseFacade facade, IDbContextTransacti public virtual ModelBuilder CreateModelBuilder() { - var context = CreateContext(); - var conventionSetBuilder = CreateConventionSetBuilder(context); - var logger = context.GetService>(); - - var conventionSet = conventionSetBuilder.CreateConventionSet(); - - conventionSet.ModelFinalizedConventions.Add( - new ValidatingConvention(context.GetService(), logger)); + var conventionSet = CreateConventionSetBuilder(CreateContext()).CreateConventionSet(); return new ModelBuilder(conventionSet); } diff --git a/test/EFCore.Specification.Tests/TestUtilities/TestHelpers.cs b/test/EFCore.Specification.Tests/TestUtilities/TestHelpers.cs index 5b2afe161af..35e91011439 100644 --- a/test/EFCore.Specification.Tests/TestUtilities/TestHelpers.cs +++ b/test/EFCore.Specification.Tests/TestUtilities/TestHelpers.cs @@ -11,8 +11,8 @@ using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Internal; using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Metadata.Conventions; using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure; -using Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal; using Microsoft.EntityFrameworkCore.Metadata.Internal; using Microsoft.EntityFrameworkCore.Storage; using Microsoft.Extensions.DependencyInjection; @@ -204,18 +204,12 @@ public IMutableModel BuildModelFor() public ModelBuilder CreateConventionBuilder(bool skipValidation = false) { - var contextServices = CreateContextServices(); - var logger = contextServices.GetService>(); - - var conventionSet = contextServices.GetRequiredService() + var conventionSet = CreateContextServices().GetRequiredService() .CreateConventionSet(); - if (!skipValidation) + if (skipValidation) { - conventionSet.ModelFinalizedConventions.Add( - new ValidatingConvention( - contextServices.GetService(), - logger)); + ConventionSet.Remove(conventionSet.ModelFinalizedConventions, typeof(ValidatingConvention)); } return new ModelBuilder(conventionSet); @@ -232,11 +226,6 @@ public ModelBuilder CreateConventionBuilder( var conventionSet = contextServices.GetRequiredService().CreateConventionSet(); - conventionSet.ModelFinalizedConventions.Add( - new ValidatingConvention( - CreateModelValidator(), - validationLogger)); - return new ModelBuilder(conventionSet); } diff --git a/test/EFCore.Specification.Tests/TestUtilities/TestModelSource.cs b/test/EFCore.Specification.Tests/TestUtilities/TestModelSource.cs index 1ba0977ae94..9d84d0ffa44 100644 --- a/test/EFCore.Specification.Tests/TestUtilities/TestModelSource.cs +++ b/test/EFCore.Specification.Tests/TestUtilities/TestModelSource.cs @@ -2,11 +2,9 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; -using Microsoft.EntityFrameworkCore.Diagnostics; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure; -using Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal; using Microsoft.Extensions.DependencyInjection; namespace Microsoft.EntityFrameworkCore.TestUtilities @@ -23,14 +21,9 @@ private TestModelSource(Action onModelCreating, ModelSo protected override IModel CreateModel( DbContext context, - IConventionSetBuilder conventionSetBuilder, - IModelValidator validator, - IDiagnosticsLogger validationLogger) + IConventionSetBuilder conventionSetBuilder) { - var conventionSet = conventionSetBuilder.CreateConventionSet(); - conventionSet.ModelFinalizedConventions.Add(new ValidatingConvention(validator, validationLogger)); - - var modelBuilder = new ModelBuilder(conventionSet); + var modelBuilder = new ModelBuilder(conventionSetBuilder.CreateConventionSet()); Dependencies.ModelCustomizer.Customize(modelBuilder, context); diff --git a/test/EFCore.Specification.Tests/TestUtilities/TestServiceFactory.cs b/test/EFCore.Specification.Tests/TestUtilities/TestServiceFactory.cs index b0fc1f490d8..ed6e689fda8 100644 --- a/test/EFCore.Specification.Tests/TestUtilities/TestServiceFactory.cs +++ b/test/EFCore.Specification.Tests/TestUtilities/TestServiceFactory.cs @@ -11,7 +11,6 @@ using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Internal; using Microsoft.EntityFrameworkCore.Metadata; -using Microsoft.EntityFrameworkCore.Metadata.Internal; using Microsoft.Extensions.DependencyInjection; namespace Microsoft.EntityFrameworkCore.TestUtilities diff --git a/test/EFCore.SqlServer.FunctionalTests/BuiltInDataTypesSqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/BuiltInDataTypesSqlServerTest.cs index 9e783452857..f9d8635b047 100644 --- a/test/EFCore.SqlServer.FunctionalTests/BuiltInDataTypesSqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/BuiltInDataTypesSqlServerTest.cs @@ -8,7 +8,7 @@ using System.Text; using Microsoft.EntityFrameworkCore.Diagnostics; using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Metadata.Internal; +using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Storage; using Microsoft.EntityFrameworkCore.TestUtilities; using Microsoft.EntityFrameworkCore.TestUtilities.Xunit; diff --git a/test/EFCore.SqlServer.FunctionalTests/SqlServerDbFunctionMetadataTests.cs b/test/EFCore.SqlServer.FunctionalTests/SqlServerDbFunctionMetadataTests.cs index d953d037411..5e07f5c075e 100644 --- a/test/EFCore.SqlServer.FunctionalTests/SqlServerDbFunctionMetadataTests.cs +++ b/test/EFCore.SqlServer.FunctionalTests/SqlServerDbFunctionMetadataTests.cs @@ -4,9 +4,9 @@ using System; using System.Reflection; using Microsoft.EntityFrameworkCore.Metadata.Conventions; -using Microsoft.EntityFrameworkCore.SqlServer.Diagnostics.Internal; -using Microsoft.EntityFrameworkCore.SqlServer.Metadata.Conventions.Internal; +using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure; using Microsoft.EntityFrameworkCore.TestUtilities; +using Microsoft.Extensions.DependencyInjection; using Xunit; // ReSharper disable InconsistentNaming @@ -69,9 +69,15 @@ private ModelBuilder GetModelBuilder() var conventionSet = new ConventionSet(); conventionSet.ModelAnnotationChangedConventions.Add( - new SqlServerDbFunctionConvention(new TestLogger())); + new SqlServerDbFunctionConvention(CreateDependencies(), CreateRelationalDependencies())); return new ModelBuilder(conventionSet); } + + private ProviderConventionSetBuilderDependencies CreateDependencies() + => SqlServerTestHelpers.Instance.CreateContextServices().GetRequiredService(); + + private RelationalConventionSetBuilderDependencies CreateRelationalDependencies() + => SqlServerTestHelpers.Instance.CreateContextServices().GetRequiredService(); } } diff --git a/test/EFCore.SqlServer.FunctionalTests/TestUtilities/TestSqlServerRetryingExecutionStrategy.cs b/test/EFCore.SqlServer.FunctionalTests/TestUtilities/TestSqlServerRetryingExecutionStrategy.cs index e483f357b05..c6ac0c3b36c 100644 --- a/test/EFCore.SqlServer.FunctionalTests/TestUtilities/TestSqlServerRetryingExecutionStrategy.cs +++ b/test/EFCore.SqlServer.FunctionalTests/TestUtilities/TestSqlServerRetryingExecutionStrategy.cs @@ -15,6 +15,7 @@ public class TestSqlServerRetryingExecutionStrategy : SqlServerRetryingExecution { -1, // Physical connection is not usable -2, // Timeout + 1807, // Could not obtain exclusive lock on database 'model' 42008, // Mirroring (Only when a database is deleted and another one is created in fast succession) 42019 // CREATE DATABASE operation failed }; diff --git a/test/EFCore.Sqlite.FunctionalTests/BuiltInDataTypesSqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/BuiltInDataTypesSqliteTest.cs index 060ad4041bb..01b2deb335f 100644 --- a/test/EFCore.Sqlite.FunctionalTests/BuiltInDataTypesSqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/BuiltInDataTypesSqliteTest.cs @@ -5,6 +5,7 @@ using System.Linq; using Microsoft.EntityFrameworkCore.Diagnostics; using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Metadata.Internal; using Microsoft.EntityFrameworkCore.Storage; using Microsoft.EntityFrameworkCore.TestUtilities; diff --git a/test/EFCore.Tests/DbContextServicesTest.cs b/test/EFCore.Tests/DbContextServicesTest.cs index 563d8c5045f..22a6c473f3f 100644 --- a/test/EFCore.Tests/DbContextServicesTest.cs +++ b/test/EFCore.Tests/DbContextServicesTest.cs @@ -15,7 +15,6 @@ using Microsoft.EntityFrameworkCore.Internal; using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure; -using Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal; using Microsoft.EntityFrameworkCore.Metadata.Internal; using Microsoft.EntityFrameworkCore.TestUtilities; using Microsoft.EntityFrameworkCore.ValueGeneration; @@ -628,9 +627,7 @@ private class FakeModelSource : IModelSource { public IModel GetModel( DbContext context, - IConventionSetBuilder conventionSetBuilder, - IModelValidator validator, - IDiagnosticsLogger validationLogger) + IConventionSetBuilder conventionSetBuilder) => new Model(); } diff --git a/test/EFCore.Tests/DbSetInitializerTest.cs b/test/EFCore.Tests/DbSetInitializerTest.cs index 43fbfee8d50..edb8728714e 100644 --- a/test/EFCore.Tests/DbSetInitializerTest.cs +++ b/test/EFCore.Tests/DbSetInitializerTest.cs @@ -37,7 +37,7 @@ public void Initializes_all_entity_set_properties_with_setters() private class FakeSetFinder : IDbSetFinder { - public IReadOnlyList FindSets(DbContext context) + public IReadOnlyList FindSets(Type contextType) { var setterFactory = new ClrPropertySetterFactory(); diff --git a/test/EFCore.Tests/EntitySetFinderTest.cs b/test/EFCore.Tests/EntitySetFinderTest.cs index 1a48d679189..dff0f689f78 100644 --- a/test/EFCore.Tests/EntitySetFinderTest.cs +++ b/test/EFCore.Tests/EntitySetFinderTest.cs @@ -7,6 +7,7 @@ using Microsoft.EntityFrameworkCore.Internal; using Xunit; +// ReSharper disable InconsistentNaming namespace Microsoft.EntityFrameworkCore { public class DbSetFinderTest @@ -16,7 +17,7 @@ public void All_non_static_DbSet_properties_are_discovered() { using (var context = new The()) { - var sets = new DbSetFinder().FindSets(context); + var sets = new DbSetFinder().FindSets(context.GetType()); Assert.Equal( new[] { "Betters", "Brandies", "Drinkings", "Stops", "Yous" }, diff --git a/test/EFCore.Tests/Infrastructure/ModelValidatorTestBase.cs b/test/EFCore.Tests/Infrastructure/ModelValidatorTestBase.cs index d2c4667b351..037c8de39f1 100644 --- a/test/EFCore.Tests/Infrastructure/ModelValidatorTestBase.cs +++ b/test/EFCore.Tests/Infrastructure/ModelValidatorTestBase.cs @@ -9,9 +9,10 @@ using Microsoft.EntityFrameworkCore.Internal; using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Metadata.Conventions; -using Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal; +using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure; using Microsoft.EntityFrameworkCore.Metadata.Internal; using Microsoft.EntityFrameworkCore.TestUtilities; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Xunit; @@ -242,13 +243,15 @@ protected virtual ModelBuilder CreateConventionlessModelBuilder(bool sensitiveDa var conventionSet = new ConventionSet(); conventionSet.ModelFinalizedConventions.Add( - new ValidatingConvention( - TestHelpers.CreateModelValidator(), - CreateValidationLogger(sensitiveDataLoggingEnabled))); + new ValidatingConvention(CreateDependencies(sensitiveDataLoggingEnabled))); return new ModelBuilder(conventionSet); } + private ProviderConventionSetBuilderDependencies CreateDependencies(bool sensitiveDataLoggingEnabled = false) + => TestHelpers.CreateContextServices().GetRequiredService() + .With(CreateValidationLogger(sensitiveDataLoggingEnabled)); + protected virtual TestHelpers TestHelpers => InMemoryTestHelpers.Instance; } } diff --git a/test/EFCore.Tests/Metadata/Conventions/Internal/BackingFieldConventionTest.cs b/test/EFCore.Tests/Metadata/Conventions/Internal/BackingFieldConventionTest.cs index df09e7a133c..9054ac1cf6b 100644 --- a/test/EFCore.Tests/Metadata/Conventions/Internal/BackingFieldConventionTest.cs +++ b/test/EFCore.Tests/Metadata/Conventions/Internal/BackingFieldConventionTest.cs @@ -5,8 +5,10 @@ using System.Reflection; using Microsoft.EntityFrameworkCore.Diagnostics; using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure; using Microsoft.EntityFrameworkCore.Metadata.Internal; using Microsoft.EntityFrameworkCore.TestUtilities; +using Microsoft.Extensions.DependencyInjection; using Xunit; // ReSharper disable ArrangeAccessorOwnerBody @@ -129,7 +131,7 @@ public void M_underscore_matching_field_is_not_used_if_type_is_not_compatible_fo Assert.Null(property.GetFieldName()); } - private static void FieldMatchTest(string propertyName, string fieldName) + private void FieldMatchTest(string propertyName, string fieldName) { var entityType = CreateModel().AddEntityType(typeof(TEntity)); var property = entityType.AddProperty(propertyName, typeof(int)); @@ -224,12 +226,15 @@ public void FieldInfo_set_by_annotation_is_used() Assert.Equal("m_onTheRun", property.GetFieldName()); } - private static void RunConvention(IMutableProperty property) - => new BackingFieldConvention(new TestLogger()) + private void RunConvention(IMutableProperty property) + => new BackingFieldConvention(CreateDependencies()) .ProcessPropertyAdded( ((Property)property).Builder, new ConventionContext(((Model)property.DeclaringEntityType.Model).ConventionDispatcher)); + private ProviderConventionSetBuilderDependencies CreateDependencies() + => InMemoryTestHelpers.Instance.CreateContextServices().GetRequiredService(); + private static IMutableModel CreateModel() => new Model(); #pragma warning disable RCS1222 // Merge preprocessor directives. diff --git a/test/EFCore.Tests/Metadata/Conventions/Internal/BaseTypeDiscoveryConventionTest.cs b/test/EFCore.Tests/Metadata/Conventions/Internal/BaseTypeDiscoveryConventionTest.cs index 250345d88af..49343cee55c 100644 --- a/test/EFCore.Tests/Metadata/Conventions/Internal/BaseTypeDiscoveryConventionTest.cs +++ b/test/EFCore.Tests/Metadata/Conventions/Internal/BaseTypeDiscoveryConventionTest.cs @@ -2,8 +2,10 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure; using Microsoft.EntityFrameworkCore.Metadata.Internal; using Microsoft.EntityFrameworkCore.TestUtilities; +using Microsoft.Extensions.DependencyInjection; using Xunit; namespace Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal @@ -52,10 +54,13 @@ private void RunConvention(InternalEntityTypeBuilder entityTypeBuilder) { var context = new ConventionContext(entityTypeBuilder.Metadata.Model.ConventionDispatcher); - new BaseTypeDiscoveryConvention(new TestLogger()) + new BaseTypeDiscoveryConvention(CreateDependencies()) .ProcessEntityTypeAdded(entityTypeBuilder, context); } + private ProviderConventionSetBuilderDependencies CreateDependencies() + => InMemoryTestHelpers.Instance.CreateContextServices().GetRequiredService(); + private class A { } diff --git a/test/EFCore.Tests/Metadata/Conventions/Internal/ConstructorBindingConventionTest.cs b/test/EFCore.Tests/Metadata/Conventions/Internal/ConstructorBindingConventionTest.cs index 7290e91c204..4d919897528 100644 --- a/test/EFCore.Tests/Metadata/Conventions/Internal/ConstructorBindingConventionTest.cs +++ b/test/EFCore.Tests/Metadata/Conventions/Internal/ConstructorBindingConventionTest.cs @@ -7,8 +7,10 @@ using Microsoft.EntityFrameworkCore.Diagnostics; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure; using Microsoft.EntityFrameworkCore.Metadata.Internal; using Microsoft.EntityFrameworkCore.TestUtilities; +using Microsoft.Extensions.DependencyInjection; using Xunit; // ReSharper disable UnassignedGetOnlyAutoProperty @@ -744,10 +746,8 @@ private class NoFieldRelated public NoField NoField { get; set; } } - private static DirectConstructorBinding GetBinding() + private DirectConstructorBinding GetBinding() { - var convention = TestServiceFactory.Instance.Create(); - var entityType = ((IMutableModel)new Model()).AddEntityType(typeof(TEntity)); entityType.AddProperty(nameof(Blog.Id), typeof(int)); entityType.AddProperty(nameof(Blog.Title), typeof(string)); @@ -764,11 +764,15 @@ private static DirectConstructorBinding GetBinding() var model = (Model)entityType.Model; var context = new ConventionContext(model.ConventionDispatcher); + var convention = new ConstructorBindingConvention(CreateDependencies()); convention.ProcessModelFinalized(model.Builder, context); return (DirectConstructorBinding)entityType[CoreAnnotationNames.ConstructorBinding]; } + private ProviderConventionSetBuilderDependencies CreateDependencies() + => InMemoryTestHelpers.Instance.CreateContextServices().GetRequiredService(); + private abstract class Blog { #pragma warning disable 649, IDE1006 // Naming Styles diff --git a/test/EFCore.Tests/Metadata/Conventions/Internal/ConventionDispatcherTest.cs b/test/EFCore.Tests/Metadata/Conventions/Internal/ConventionDispatcherTest.cs index ef360841b5f..c2245769f54 100644 --- a/test/EFCore.Tests/Metadata/Conventions/Internal/ConventionDispatcherTest.cs +++ b/test/EFCore.Tests/Metadata/Conventions/Internal/ConventionDispatcherTest.cs @@ -342,6 +342,7 @@ public void ProcessEntityTypeAdded( if (_onlyWeak) { entityTypeBuilder.ModelBuilder.HasNoEntityType(entityTypeBuilder.Metadata); + context.StopProcessing(); } } else @@ -349,9 +350,9 @@ public void ProcessEntityTypeAdded( if (!_onlyWeak) { entityTypeBuilder.Metadata.Model.RemoveEntityType(entityTypeBuilder.Metadata.Name); + context.StopProcessing(); } } - context.StopProcessing(); } } } diff --git a/test/EFCore.Tests/Metadata/Conventions/Internal/DerivedTypeDiscoveryConventionTest.cs b/test/EFCore.Tests/Metadata/Conventions/Internal/DerivedTypeDiscoveryConventionTest.cs index 687d9c44dc3..67a8901da1e 100644 --- a/test/EFCore.Tests/Metadata/Conventions/Internal/DerivedTypeDiscoveryConventionTest.cs +++ b/test/EFCore.Tests/Metadata/Conventions/Internal/DerivedTypeDiscoveryConventionTest.cs @@ -3,8 +3,10 @@ using Microsoft.EntityFrameworkCore.Diagnostics; using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure; using Microsoft.EntityFrameworkCore.Metadata.Internal; using Microsoft.EntityFrameworkCore.TestUtilities; +using Microsoft.Extensions.DependencyInjection; using Xunit; namespace Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal @@ -59,14 +61,17 @@ public void Discovers_child_type_if_base_type_set() Assert.Same(entityBuilderB.Metadata, entityBuilderC.Metadata.BaseType); } - private static void RunConvention(InternalEntityTypeBuilder entityTypeBuilder) + private void RunConvention(InternalEntityTypeBuilder entityTypeBuilder) { var context = new ConventionContext(entityTypeBuilder.Metadata.Model.ConventionDispatcher); - new DerivedTypeDiscoveryConvention(new TestLogger()) + new DerivedTypeDiscoveryConvention(CreateDependencies()) .ProcessEntityTypeAdded(entityTypeBuilder, context); } + private ProviderConventionSetBuilderDependencies CreateDependencies() + => InMemoryTestHelpers.Instance.CreateContextServices().GetRequiredService(); + private class A { } diff --git a/test/EFCore.Tests/Metadata/Conventions/Internal/EntityTypeAttributeConventionTest.cs b/test/EFCore.Tests/Metadata/Conventions/Internal/EntityTypeAttributeConventionTest.cs index ba994da9d45..29dd7fe2b49 100644 --- a/test/EFCore.Tests/Metadata/Conventions/Internal/EntityTypeAttributeConventionTest.cs +++ b/test/EFCore.Tests/Metadata/Conventions/Internal/EntityTypeAttributeConventionTest.cs @@ -3,10 +3,11 @@ using System.ComponentModel.DataAnnotations.Schema; using System.Linq; -using Microsoft.EntityFrameworkCore.Diagnostics; using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure; using Microsoft.EntityFrameworkCore.Metadata.Internal; using Microsoft.EntityFrameworkCore.TestUtilities; +using Microsoft.Extensions.DependencyInjection; using Xunit; // ReSharper disable UnusedMember.Local @@ -57,10 +58,13 @@ private void RunConvention(InternalEntityTypeBuilder entityTypeBuilder) { var context = new ConventionContext(entityTypeBuilder.Metadata.Model.ConventionDispatcher); - new NotMappedEntityTypeAttributeConvention(new TestLogger()) + new NotMappedEntityTypeAttributeConvention(CreateDependencies()) .ProcessEntityTypeAdded(entityTypeBuilder, context); } + private ProviderConventionSetBuilderDependencies CreateDependencies() + => InMemoryTestHelpers.Instance.CreateContextServices().GetRequiredService(); + [NotMapped] private class A { diff --git a/test/EFCore.Tests/Metadata/Conventions/Internal/ForeignKeyPropertyDiscoveryConventionTest.cs b/test/EFCore.Tests/Metadata/Conventions/Internal/ForeignKeyPropertyDiscoveryConventionTest.cs index 430a77665c6..7aa872aa34c 100644 --- a/test/EFCore.Tests/Metadata/Conventions/Internal/ForeignKeyPropertyDiscoveryConventionTest.cs +++ b/test/EFCore.Tests/Metadata/Conventions/Internal/ForeignKeyPropertyDiscoveryConventionTest.cs @@ -10,8 +10,10 @@ using Microsoft.EntityFrameworkCore.Diagnostics.Internal; using Microsoft.EntityFrameworkCore.Internal; using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure; using Microsoft.EntityFrameworkCore.Metadata.Internal; using Microsoft.EntityFrameworkCore.TestUtilities; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Xunit; @@ -1067,12 +1069,24 @@ private ForeignKeyPropertyDiscoveryConvention CreateForeignKeyPropertyDiscoveryC ListLoggerFactory.Clear(); var options = new LoggingOptions(); options.Initialize(new DbContextOptionsBuilder().EnableSensitiveDataLogging(false).Options); - return new ForeignKeyPropertyDiscoveryConvention( - new DiagnosticsLogger( - ListLoggerFactory, - options, - new DiagnosticListener("Fake"), - new TestLoggingDefinitions())); + return new ForeignKeyPropertyDiscoveryConvention(CreateDependencies()); + } + + private ProviderConventionSetBuilderDependencies CreateDependencies() + => InMemoryTestHelpers.Instance.CreateContextServices().GetRequiredService() + .With(CreateLogger()); + + private DiagnosticsLogger CreateLogger() + { + ListLoggerFactory.Clear(); + var options = new LoggingOptions(); + options.Initialize(new DbContextOptionsBuilder().EnableSensitiveDataLogging(false).Options); + var modelLogger = new DiagnosticsLogger( + ListLoggerFactory, + options, + new DiagnosticListener("Fake"), + new TestLoggingDefinitions()); + return modelLogger; } public ListLoggerFactory ListLoggerFactory { get; } diff --git a/test/EFCore.Tests/Metadata/Conventions/Internal/KeyDiscoveryConventionTest.cs b/test/EFCore.Tests/Metadata/Conventions/Internal/KeyDiscoveryConventionTest.cs index 885c35511a2..da26c67ab14 100644 --- a/test/EFCore.Tests/Metadata/Conventions/Internal/KeyDiscoveryConventionTest.cs +++ b/test/EFCore.Tests/Metadata/Conventions/Internal/KeyDiscoveryConventionTest.cs @@ -5,11 +5,12 @@ using System.Diagnostics; using System.Linq; using Microsoft.EntityFrameworkCore.Diagnostics.Internal; -using Microsoft.EntityFrameworkCore.InMemory.Storage.Internal; using Microsoft.EntityFrameworkCore.Internal; using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure; using Microsoft.EntityFrameworkCore.Metadata.Internal; using Microsoft.EntityFrameworkCore.TestUtilities; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Xunit; @@ -152,7 +153,11 @@ private void RunConvention(InternalPropertyBuilder propertyBuilder) CreateKeyDiscoveryConvention().ProcessPropertyAdded(propertyBuilder, context); } - private KeyDiscoveryConvention CreateKeyDiscoveryConvention() => new KeyDiscoveryConvention(CreateLogger()); + private KeyDiscoveryConvention CreateKeyDiscoveryConvention() => new KeyDiscoveryConvention(CreateDependencies()); + + private ProviderConventionSetBuilderDependencies CreateDependencies() + => InMemoryTestHelpers.Instance.CreateContextServices().GetRequiredService() + .With(CreateLogger()); private DiagnosticsLogger CreateLogger() { @@ -167,15 +172,13 @@ private void RunConvention(InternalPropertyBuilder propertyBuilder) return modelLogger; } - private static InternalEntityTypeBuilder CreateInternalEntityBuilder() + private InternalEntityTypeBuilder CreateInternalEntityBuilder() { var modelBuilder = new InternalModelBuilder(new Model()); var entityBuilder = modelBuilder.Entity(typeof(T), ConfigurationSource.Convention); var context = new ConventionContext(modelBuilder.Metadata.ConventionDispatcher); - new PropertyDiscoveryConvention( - TestServiceFactory.Instance.Create(), - new TestLogger()) + new PropertyDiscoveryConvention(CreateDependencies()) .ProcessEntityTypeAdded(entityBuilder, context); return entityBuilder; diff --git a/test/EFCore.Tests/Metadata/Conventions/Internal/ModelCleanupConventionTest.cs b/test/EFCore.Tests/Metadata/Conventions/Internal/ModelCleanupConventionTest.cs index 68477e62eba..d576d1b8c19 100644 --- a/test/EFCore.Tests/Metadata/Conventions/Internal/ModelCleanupConventionTest.cs +++ b/test/EFCore.Tests/Metadata/Conventions/Internal/ModelCleanupConventionTest.cs @@ -3,8 +3,10 @@ using System.Linq; using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure; using Microsoft.EntityFrameworkCore.Metadata.Internal; using Microsoft.EntityFrameworkCore.TestUtilities; +using Microsoft.Extensions.DependencyInjection; using Xunit; namespace Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal @@ -68,10 +70,13 @@ private void RunConvention(InternalModelBuilder modelBuilder) { var context = new ConventionContext(modelBuilder.Metadata.ConventionDispatcher); - new ModelCleanupConvention(new TestLogger()) + new ModelCleanupConvention(CreateDependencies()) .ProcessModelFinalized(modelBuilder, context); } + private ProviderConventionSetBuilderDependencies CreateDependencies() + => InMemoryTestHelpers.Instance.CreateContextServices().GetRequiredService(); + private static InternalEntityTypeBuilder CreateInternalEntityBuilder() { var modelBuilder = new InternalModelBuilder(new Model()); diff --git a/test/EFCore.Tests/Metadata/Conventions/Internal/NavigationAttributeConventionTest.cs b/test/EFCore.Tests/Metadata/Conventions/Internal/NavigationAttributeConventionTest.cs index 177a83e146a..96026d90e34 100644 --- a/test/EFCore.Tests/Metadata/Conventions/Internal/NavigationAttributeConventionTest.cs +++ b/test/EFCore.Tests/Metadata/Conventions/Internal/NavigationAttributeConventionTest.cs @@ -11,12 +11,10 @@ using Microsoft.EntityFrameworkCore.Diagnostics; using Microsoft.EntityFrameworkCore.Diagnostics.Internal; using Microsoft.EntityFrameworkCore.InMemory.Metadata.Conventions; -using Microsoft.EntityFrameworkCore.InMemory.Storage.Internal; using Microsoft.EntityFrameworkCore.Internal; using Microsoft.EntityFrameworkCore.Metadata.Builders; using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure; using Microsoft.EntityFrameworkCore.Metadata.Internal; -using Microsoft.EntityFrameworkCore.Storage; using Microsoft.EntityFrameworkCore.TestUtilities; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; @@ -334,7 +332,7 @@ public void InversePropertyAttribute_does_not_configure_ambiguous_navigations() dependentEntityTypeBuilder.Metadata.GetNavigations(), nav => nav.Name == nameof(AmbiguousDependent.AnotherAmbiguousPrincipal)); - var convention = CreateInversePropertyAttributeConvention(); + var convention = new InversePropertyAttributeConvention(CreateDependencies(CreateLogger())); convention.ProcessEntityTypeAdded(dependentEntityTypeBuilder, new ConventionContext( dependentEntityTypeBuilder.Metadata.Model.ConventionDispatcher)); @@ -378,7 +376,7 @@ public void InversePropertyAttribute_does_not_configure_non_defining_navigation( Assert.DoesNotContain(principalEntityTypeBuilder.Metadata.GetNavigations(), nav => nav.Name == nameof(Principal.Dependent)); Assert.Contains(dependentEntityTypeBuilder.Metadata.GetNavigations(), nav => nav.Name == nameof(Dependent.Principal)); - var convention = CreateInversePropertyAttributeConvention(); + var convention = new InversePropertyAttributeConvention(CreateDependencies(CreateLogger())); convention.ProcessEntityTypeAdded(dependentEntityTypeBuilder, new ConventionContext( dependentEntityTypeBuilder.Metadata.Model.ConventionDispatcher)); @@ -411,7 +409,7 @@ public void InversePropertyAttribute_does_not_configure_non_ownership_navigation Assert.DoesNotContain(principalEntityTypeBuilder.Metadata.GetNavigations(), nav => nav.Name == nameof(Principal.Dependent)); Assert.DoesNotContain(dependentEntityTypeBuilder.Metadata.GetNavigations(), nav => nav.Name == nameof(Dependent.Principal)); - var convention = CreateInversePropertyAttributeConvention(); + var convention = new InversePropertyAttributeConvention(CreateDependencies(CreateLogger())); convention.ProcessEntityTypeAdded(dependentEntityTypeBuilder, new ConventionContext( dependentEntityTypeBuilder.Metadata.Model.ConventionDispatcher)); @@ -591,11 +589,6 @@ public void ForeignKeyAttribute_sets_foreign_key_properties_when_applied_on_prin Assert.Equal("PrincipalAnotherFk", relationshipBuilder.Metadata.Properties.First().Name); } - private ForeignKeyAttributeConvention CreateForeignKeyAttributeConvention() - => new ForeignKeyAttributeConvention( - CreateMemberClassifier(), - CreateLogger()); - [Fact] public void ForeignKeyAttribute_sets_foreign_key_properties_when_applied_on_property_on_dependent_side() { @@ -809,54 +802,55 @@ public void ForeignKeyAttribute_throws_when_specified_on_principal_property_with private void RunConvention(InternalEntityTypeBuilder entityTypeBuilder) { - var context = new ConventionContext(entityTypeBuilder.Metadata.Model.ConventionDispatcher); + var dependencies = CreateDependencies(CreateLogger()); + var context = new ConventionContext( + entityTypeBuilder.Metadata.Model.ConventionDispatcher); - new NotMappedMemberAttributeConvention(new TestLogger()) + new NotMappedMemberAttributeConvention(dependencies) .ProcessEntityTypeAdded(entityTypeBuilder, context); - new RelationshipDiscoveryConvention(CreateMemberClassifier(), CreateLogger()) + new RelationshipDiscoveryConvention(dependencies) .ProcessEntityTypeAdded(entityTypeBuilder, context); - CreateInversePropertyAttributeConvention() + new InversePropertyAttributeConvention(dependencies) .ProcessEntityTypeAdded(entityTypeBuilder, context); } private InternalRelationshipBuilder RunConvention(InternalRelationshipBuilder relationshipBuilder) { + var dependencies = CreateDependencies(CreateLogger()); var context = new ConventionContext( relationshipBuilder.Metadata.DeclaringEntityType.Model.ConventionDispatcher); - CreateForeignKeyAttributeConvention().ProcessForeignKeyAdded(relationshipBuilder, context); + new ForeignKeyAttributeConvention(dependencies) + .ProcessForeignKeyAdded(relationshipBuilder, context); return context.ShouldStopProcessing() ? (InternalRelationshipBuilder)context.Result : relationshipBuilder; } private void RunConvention(InternalRelationshipBuilder relationshipBuilder, Navigation navigation) { + var dependencies = CreateDependencies(CreateLogger()); var context = new ConventionContext( relationshipBuilder.Metadata.DeclaringEntityType.Model.ConventionDispatcher); - CreateRequiredNavigationAttributeConvention().ProcessNavigationAdded(relationshipBuilder, navigation, context); + new RequiredNavigationAttributeConvention(dependencies) + .ProcessNavigationAdded(relationshipBuilder, navigation, context); } - private InversePropertyAttributeConvention CreateInversePropertyAttributeConvention() - => new InversePropertyAttributeConvention( - CreateMemberClassifier(), - CreateLogger()); - private void Validate(InternalEntityTypeBuilder entityTypeBuilder) { - var logger = CreateLogger(); + var dependencies = CreateDependencies(CreateLogger()); var context = new ConventionContext( entityTypeBuilder.Metadata.Model.ConventionDispatcher); - new KeyAttributeConvention(logger) + new KeyAttributeConvention(dependencies) .ProcessModelFinalized(entityTypeBuilder.ModelBuilder, context); - new InversePropertyAttributeConvention(CreateMemberClassifier(), logger) + new InversePropertyAttributeConvention(dependencies) .ProcessModelFinalized(entityTypeBuilder.ModelBuilder, context); - new ForeignKeyAttributeConvention(CreateMemberClassifier(), logger) + new ForeignKeyAttributeConvention(dependencies) .ProcessModelFinalized(entityTypeBuilder.ModelBuilder, context); } @@ -871,38 +865,25 @@ public void Navigation_attribute_convention_runs_for_private_property() Assert.False(referenceBuilder.Metadata.Properties.First().IsNullable); } - private RequiredNavigationAttributeConvention CreateRequiredNavigationAttributeConvention() - => new RequiredNavigationAttributeConvention(CreateLogger()); - public ListLoggerFactory ListLoggerFactory { get; } = new ListLoggerFactory(l => l == DbLoggerCategory.Model.Name); private InternalEntityTypeBuilder CreateInternalEntityTypeBuilder() { + var dependencies = CreateDependencies(CreateLogger()); var conventionSet = new ConventionSet(); - conventionSet.EntityTypeAddedConventions.Add( - new PropertyDiscoveryConvention( - CreateTypeMapper(), - new TestLogger())); + conventionSet.EntityTypeAddedConventions.Add(new PropertyDiscoveryConvention(dependencies)); - conventionSet.EntityTypeAddedConventions.Add(new KeyDiscoveryConvention(CreateLogger())); + conventionSet.EntityTypeAddedConventions.Add(new KeyDiscoveryConvention(dependencies)); var modelBuilder = new InternalModelBuilder(new Model(conventionSet)); return modelBuilder.Entity(typeof(T), ConfigurationSource.Explicit); } - private static IMemberClassifier CreateMemberClassifier() - => new MemberClassifier(CreateTypeMapper(), TestServiceFactory.Instance.Create()); - - private static ITypeMappingSource CreateTypeMapper() - => TestServiceFactory.Instance.Create(); - private ModelBuilder CreateModelBuilder() { - var contextServices = InMemoryTestHelpers.Instance.CreateContextServices(); - var logger = CreateLogger(); - var dependencies = contextServices.GetRequiredService().With(logger); + var dependencies = CreateDependencies(CreateLogger()); return new ModelBuilder( new RuntimeConventionSetBuilder( @@ -911,6 +892,9 @@ private ModelBuilder CreateModelBuilder() .CreateConventionSet()); } + private static ProviderConventionSetBuilderDependencies CreateDependencies(DiagnosticsLogger logger) + => InMemoryTestHelpers.Instance.CreateContextServices().GetRequiredService().With(logger); + private DiagnosticsLogger CreateLogger() { ListLoggerFactory.Clear(); diff --git a/test/EFCore.Tests/Metadata/Conventions/Internal/NonNullableNavigationConventionTest.cs b/test/EFCore.Tests/Metadata/Conventions/Internal/NonNullableNavigationConventionTest.cs index 814a39390f9..4187216501f 100644 --- a/test/EFCore.Tests/Metadata/Conventions/Internal/NonNullableNavigationConventionTest.cs +++ b/test/EFCore.Tests/Metadata/Conventions/Internal/NonNullableNavigationConventionTest.cs @@ -7,11 +7,9 @@ using System.Linq; using System.Reflection; using Microsoft.EntityFrameworkCore.Diagnostics.Internal; -using Microsoft.EntityFrameworkCore.InMemory.Storage.Internal; using Microsoft.EntityFrameworkCore.Internal; using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure; using Microsoft.EntityFrameworkCore.Metadata.Internal; -using Microsoft.EntityFrameworkCore.Storage; using Microsoft.EntityFrameworkCore.TestUtilities; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; @@ -188,7 +186,7 @@ private Navigation RunConvention(InternalRelationshipBuilder relationshipBuilder } private NonNullableNavigationConvention CreateNotNullNavigationConvention() - => new NonNullableNavigationConvention(CreateLogger()); + => new NonNullableNavigationConvention(CreateDependencies()); public ListLoggerFactory ListLoggerFactory { get; } = new ListLoggerFactory(l => l == DbLoggerCategory.Model.Name); @@ -197,25 +195,18 @@ private InternalEntityTypeBuilder CreateInternalEntityTypeBuilder() { var conventionSet = new ConventionSet(); conventionSet.EntityTypeAddedConventions.Add( - new PropertyDiscoveryConvention( - CreateTypeMapper(), - new TestLogger())); + new PropertyDiscoveryConvention(CreateDependencies())); - conventionSet.EntityTypeAddedConventions.Add(new KeyDiscoveryConvention(CreateLogger())); + conventionSet.EntityTypeAddedConventions.Add(new KeyDiscoveryConvention(CreateDependencies())); var modelBuilder = new InternalModelBuilder(new Model(conventionSet)); return modelBuilder.Entity(typeof(T), ConfigurationSource.Explicit); } - private static ITypeMappingSource CreateTypeMapper() - => TestServiceFactory.Instance.Create(); - private ModelBuilder CreateModelBuilder() { - var contextServices = InMemoryTestHelpers.Instance.CreateContextServices(); - var logger = CreateLogger(); - var dependencies = contextServices.GetRequiredService().With(logger); + var dependencies = CreateDependencies(); return new ModelBuilder( new RuntimeConventionSetBuilder( @@ -224,6 +215,10 @@ private ModelBuilder CreateModelBuilder() .CreateConventionSet()); } + private ProviderConventionSetBuilderDependencies CreateDependencies() + => InMemoryTestHelpers.Instance.CreateContextServices().GetRequiredService() + .With(CreateLogger()); + private DiagnosticsLogger CreateLogger() { ListLoggerFactory.Clear(); diff --git a/test/EFCore.Tests/Metadata/Conventions/Internal/NonNullableReferencePropertyConventionTest.cs b/test/EFCore.Tests/Metadata/Conventions/Internal/NonNullableReferencePropertyConventionTest.cs index 272645b0fbc..d10adeae3df 100644 --- a/test/EFCore.Tests/Metadata/Conventions/Internal/NonNullableReferencePropertyConventionTest.cs +++ b/test/EFCore.Tests/Metadata/Conventions/Internal/NonNullableReferencePropertyConventionTest.cs @@ -2,11 +2,11 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System.ComponentModel.DataAnnotations; -using Microsoft.EntityFrameworkCore.InMemory.Storage.Internal; using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure; using Microsoft.EntityFrameworkCore.Metadata.Internal; -using Microsoft.EntityFrameworkCore.Storage; using Microsoft.EntityFrameworkCore.TestUtilities; +using Microsoft.Extensions.DependencyInjection; using Xunit; namespace Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal @@ -64,12 +64,12 @@ public void Reference_nullability_sets_is_nullable_correctly(string propertyName Assert.Equal(expectedNullable, entityTypeBuilder.Property(propertyName).Metadata.IsNullable); } - private static void RunConvention(InternalPropertyBuilder propertyBuilder) + private void RunConvention(InternalPropertyBuilder propertyBuilder) { var context = new ConventionContext( propertyBuilder.Metadata.DeclaringEntityType.Model.ConventionDispatcher); - new NonNullableReferencePropertyConvention(new TestLogger()) + new NonNullableReferencePropertyConvention(CreateDependencies()) .ProcessPropertyAdded(propertyBuilder, context); } @@ -77,17 +77,15 @@ private InternalEntityTypeBuilder CreateInternalEntityTypeBuilder() { var conventionSet = new ConventionSet(); conventionSet.EntityTypeAddedConventions.Add( - new PropertyDiscoveryConvention( - CreateTypeMapper(), - new TestLogger())); + new PropertyDiscoveryConvention(CreateDependencies())); var modelBuilder = new InternalModelBuilder(new Model(conventionSet)); return modelBuilder.Entity(typeof(T), ConfigurationSource.Explicit); } - private static ITypeMappingSource CreateTypeMapper() - => TestServiceFactory.Instance.Create(); + private ProviderConventionSetBuilderDependencies CreateDependencies() + => InMemoryTestHelpers.Instance.CreateContextServices().GetRequiredService(); private class A { diff --git a/test/EFCore.Tests/Metadata/Conventions/Internal/PropertyAttributeConventionTest.cs b/test/EFCore.Tests/Metadata/Conventions/Internal/PropertyAttributeConventionTest.cs index f4cc0e6ea6c..1947b52ba4a 100644 --- a/test/EFCore.Tests/Metadata/Conventions/Internal/PropertyAttributeConventionTest.cs +++ b/test/EFCore.Tests/Metadata/Conventions/Internal/PropertyAttributeConventionTest.cs @@ -9,9 +9,11 @@ using Microsoft.EntityFrameworkCore.Diagnostics; using Microsoft.EntityFrameworkCore.InMemory.Storage.Internal; using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure; using Microsoft.EntityFrameworkCore.Metadata.Internal; using Microsoft.EntityFrameworkCore.Storage; using Microsoft.EntityFrameworkCore.TestUtilities; +using Microsoft.Extensions.DependencyInjection; using Xunit; // ReSharper disable InconsistentNaming @@ -533,9 +535,7 @@ private InternalEntityTypeBuilder CreateInternalEntityTypeBuilder() { var conventionSet = new ConventionSet(); conventionSet.EntityTypeAddedConventions.Add( - new PropertyDiscoveryConvention( - CreateTypeMapper(), - new TestLogger())); + new PropertyDiscoveryConvention(CreateDependencies())); var modelBuilder = new InternalModelBuilder(new Model(conventionSet)); @@ -544,28 +544,29 @@ private InternalEntityTypeBuilder CreateInternalEntityTypeBuilder() private static void RunConvention(InternalPropertyBuilder propertyBuilder) { + var dependencies = CreateDependencies(); var context = new ConventionContext( propertyBuilder.Metadata.DeclaringEntityType.Model.ConventionDispatcher); - new ConcurrencyCheckAttributeConvention(new TestLogger()) + new ConcurrencyCheckAttributeConvention(dependencies) .ProcessPropertyAdded(propertyBuilder, context); - new DatabaseGeneratedAttributeConvention(new TestLogger()) + new DatabaseGeneratedAttributeConvention(dependencies) .ProcessPropertyAdded(propertyBuilder, context); - new KeyAttributeConvention(new TestLogger()) + new KeyAttributeConvention(dependencies) .ProcessPropertyAdded(propertyBuilder, context); - new MaxLengthAttributeConvention(new TestLogger()) + new MaxLengthAttributeConvention(dependencies) .ProcessPropertyAdded(propertyBuilder, context); - new RequiredPropertyAttributeConvention(new TestLogger()) + new RequiredPropertyAttributeConvention(dependencies) .ProcessPropertyAdded(propertyBuilder, context); - new StringLengthAttributeConvention(new TestLogger()) + new StringLengthAttributeConvention(dependencies) .ProcessPropertyAdded(propertyBuilder, context); - new TimestampAttributeConvention(new TestLogger()) + new TimestampAttributeConvention(dependencies) .ProcessPropertyAdded(propertyBuilder, context); } @@ -573,7 +574,7 @@ private void RunConvention(InternalEntityTypeBuilder entityTypeBuilder) { var context = new ConventionContext(entityTypeBuilder.Metadata.Model.ConventionDispatcher); - new NotMappedMemberAttributeConvention(new TestLogger()) + new NotMappedMemberAttributeConvention(CreateDependencies()) .ProcessEntityTypeAdded(entityTypeBuilder, context); } @@ -582,12 +583,12 @@ private void Validate(InternalEntityTypeBuilder entityTypeBuilder) var context = new ConventionContext( entityTypeBuilder.Metadata.Model.ConventionDispatcher); - new KeyAttributeConvention(new TestLogger()) + new KeyAttributeConvention(CreateDependencies()) .ProcessModelFinalized(entityTypeBuilder.ModelBuilder, context); } - private ITypeMappingSource CreateTypeMapper() - => TestServiceFactory.Instance.Create(); + private static ProviderConventionSetBuilderDependencies CreateDependencies() + => InMemoryTestHelpers.Instance.CreateContextServices().GetRequiredService(); private class A { diff --git a/test/EFCore.Tests/Metadata/Conventions/Internal/PropertyDiscoveryConventionTest.cs b/test/EFCore.Tests/Metadata/Conventions/Internal/PropertyDiscoveryConventionTest.cs index c7b5f683b79..de318ab7ee7 100644 --- a/test/EFCore.Tests/Metadata/Conventions/Internal/PropertyDiscoveryConventionTest.cs +++ b/test/EFCore.Tests/Metadata/Conventions/Internal/PropertyDiscoveryConventionTest.cs @@ -4,10 +4,11 @@ using System; using System.Linq; using System.Reflection; -using Microsoft.EntityFrameworkCore.InMemory.Storage.Internal; using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure; using Microsoft.EntityFrameworkCore.Metadata.Internal; using Microsoft.EntityFrameworkCore.TestUtilities; +using Microsoft.Extensions.DependencyInjection; using Xunit; // ReSharper disable UnassignedGetOnlyAutoProperty @@ -236,13 +237,15 @@ private void RunConvention(InternalEntityTypeBuilder entityTypeBuilder) { var context = new ConventionContext(entityTypeBuilder.Metadata.Model.ConventionDispatcher); - new PropertyDiscoveryConvention(TestServiceFactory.Instance.Create(), - new TestLogger()) + new PropertyDiscoveryConvention(CreateDependencies()) .ProcessEntityTypeAdded(entityTypeBuilder, context); Assert.False(context.ShouldStopProcessing()); } + private ProviderConventionSetBuilderDependencies CreateDependencies() + => InMemoryTestHelpers.Instance.CreateContextServices().GetRequiredService(); + private InternalEntityTypeBuilder CreateInternalEntityBuilder() { var modelBuilder = new InternalModelBuilder(new Model()); diff --git a/test/EFCore.Tests/Metadata/Conventions/Internal/RelationshipDiscoveryConventionTest.cs b/test/EFCore.Tests/Metadata/Conventions/Internal/RelationshipDiscoveryConventionTest.cs index 6de5f399498..ece4b7e2df5 100644 --- a/test/EFCore.Tests/Metadata/Conventions/Internal/RelationshipDiscoveryConventionTest.cs +++ b/test/EFCore.Tests/Metadata/Conventions/Internal/RelationshipDiscoveryConventionTest.cs @@ -11,8 +11,10 @@ using Microsoft.EntityFrameworkCore.InMemory.Storage.Internal; using Microsoft.EntityFrameworkCore.Internal; using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure; using Microsoft.EntityFrameworkCore.Metadata.Internal; using Microsoft.EntityFrameworkCore.TestUtilities; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Xunit; @@ -1108,17 +1110,19 @@ private InternalEntityTypeBuilder RunConvention(InternalEntityTypeBuilder entity } private RelationshipDiscoveryConvention CreateRelationshipDiscoveryConvention() - => new RelationshipDiscoveryConvention( - CreateMemberClassifier(), - CreateLogger()); + => new RelationshipDiscoveryConvention(CreateDependencies()); - private static void Cleanup(InternalModelBuilder modelBuilder) + private void Cleanup(InternalModelBuilder modelBuilder) { - new ModelCleanupConvention(new TestLogger()) + new ModelCleanupConvention(CreateDependencies()) .ProcessModelFinalized(modelBuilder, new ConventionContext(modelBuilder.Metadata.ConventionDispatcher)); } + private ProviderConventionSetBuilderDependencies CreateDependencies() + => InMemoryTestHelpers.Instance.CreateContextServices().GetRequiredService() + .With(CreateLogger()); + private InternalEntityTypeBuilder CreateInternalEntityBuilder(params Action[] onEntityAdded) { var conventions = new ConventionSet(); diff --git a/test/EFCore.Tests/Metadata/Conventions/Internal/ServicePropertyDiscoveryConventionTest.cs b/test/EFCore.Tests/Metadata/Conventions/Internal/ServicePropertyDiscoveryConventionTest.cs index 4b75773c835..ea5533bffef 100644 --- a/test/EFCore.Tests/Metadata/Conventions/Internal/ServicePropertyDiscoveryConventionTest.cs +++ b/test/EFCore.Tests/Metadata/Conventions/Internal/ServicePropertyDiscoveryConventionTest.cs @@ -7,9 +7,11 @@ using Microsoft.EntityFrameworkCore.InMemory.Storage.Internal; using Microsoft.EntityFrameworkCore.Internal; using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure; using Microsoft.EntityFrameworkCore.Metadata.Internal; using Microsoft.EntityFrameworkCore.Storage; using Microsoft.EntityFrameworkCore.TestUtilities; +using Microsoft.Extensions.DependencyInjection; using Xunit; // ReSharper disable MemberCanBePrivate.Local @@ -90,24 +92,24 @@ public void Finds_service_property_duplicate_ignored() Validate(entityType); } - private static void Validate(EntityType entityType) + private void Validate(EntityType entityType) { var convention = CreateServicePropertyDiscoveryConvention(); convention.ProcessModelFinalized(entityType.Model.Builder, new ConventionContext(entityType.Model.ConventionDispatcher)); } - private static void RunConvention(EntityType entityType, string ignoredMember) + private void RunConvention(EntityType entityType, string ignoredMember) { var convention = CreateServicePropertyDiscoveryConvention(); convention.ProcessEntityTypeMemberIgnored(entityType.Builder, ignoredMember, new ConventionContext(entityType.Model.ConventionDispatcher)); } - private static EntityType RunConvention() + private EntityType RunConvention() => RunConvention(new Model().AddEntityType(typeof(TEntity), ConfigurationSource.Explicit)); - private static EntityType RunConvention(EntityType entityType) + private EntityType RunConvention(EntityType entityType) { entityType.AddProperty(nameof(Blog.Id), typeof(int), ConfigurationSource.Explicit, ConfigurationSource.Explicit); @@ -117,14 +119,15 @@ private static EntityType RunConvention(EntityType entityType) return context.ShouldStopProcessing() ? (EntityType)context.Result.Metadata : entityType; } - private static ServicePropertyDiscoveryConvention CreateServicePropertyDiscoveryConvention() + private ServicePropertyDiscoveryConvention CreateServicePropertyDiscoveryConvention() { - var typeMappingSource = TestServiceFactory.Instance.Create(); - var convention = TestServiceFactory.Instance.Create( - (typeof(ITypeMappingSource), typeMappingSource)); + var convention = new ServicePropertyDiscoveryConvention(CreateDependencies()); return convention; } + private ProviderConventionSetBuilderDependencies CreateDependencies() + => InMemoryTestHelpers.Instance.CreateContextServices().GetRequiredService(); + private class BlogOneService : Blog { public ILazyLoader Loader { get; set; } diff --git a/test/EFCore.Tests/Metadata/Conventions/Internal/ValueGeneratorConventionTest.cs b/test/EFCore.Tests/Metadata/Conventions/Internal/ValueGeneratorConventionTest.cs index e59cca85a8e..9faff343f0c 100644 --- a/test/EFCore.Tests/Metadata/Conventions/Internal/ValueGeneratorConventionTest.cs +++ b/test/EFCore.Tests/Metadata/Conventions/Internal/ValueGeneratorConventionTest.cs @@ -3,10 +3,11 @@ using System.Collections.Generic; using System.Linq; -using Microsoft.EntityFrameworkCore.InMemory.Storage.Internal; using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure; using Microsoft.EntityFrameworkCore.Metadata.Internal; using Microsoft.EntityFrameworkCore.TestUtilities; +using Microsoft.Extensions.DependencyInjection; using Xunit; // ReSharper disable InconsistentNaming @@ -494,7 +495,7 @@ public void Identity_is_added_when_foreign_key_is_removed_and_key_is_primary_key private static void RunConvention(InternalEntityTypeBuilder entityBuilder) { - new ValueGeneratorConvention(new TestLogger()) + new ValueGeneratorConvention(CreateDependencies()) .ProcessEntityTypePrimaryKeyChanged( entityBuilder, entityBuilder.Metadata.FindPrimaryKey(), null, new ConventionContext(entityBuilder.Metadata.Model.ConventionDispatcher)); @@ -502,7 +503,7 @@ private static void RunConvention(InternalEntityTypeBuilder entityBuilder) private static void RunConvention(InternalRelationshipBuilder foreignKeyBuilder) { - new ValueGeneratorConvention(new TestLogger()) + new ValueGeneratorConvention(CreateDependencies()) .ProcessForeignKeyAdded( foreignKeyBuilder, new ConventionContext( @@ -511,24 +512,24 @@ private static void RunConvention(InternalRelationshipBuilder foreignKeyBuilder) private static void RunConvention(InternalEntityTypeBuilder entityBuilder, ForeignKey foreignKey) { - new ValueGeneratorConvention(new TestLogger()) + new ValueGeneratorConvention(CreateDependencies()) .ProcessForeignKeyRemoved(entityBuilder, foreignKey, new ConventionContext(entityBuilder.Metadata.Model.ConventionDispatcher)); } + private static ProviderConventionSetBuilderDependencies CreateDependencies() + => InMemoryTestHelpers.Instance.CreateContextServices().GetRequiredService(); + private static InternalModelBuilder CreateInternalModelBuilder() { var conventions = new ConventionSet(); - var logger = new TestLogger(); + var dependencies = CreateDependencies(); - conventions.EntityTypeAddedConventions.Add( - new PropertyDiscoveryConvention( - TestServiceFactory.Instance.Create(), - logger)); + conventions.EntityTypeAddedConventions.Add(new PropertyDiscoveryConvention(dependencies)); - conventions.EntityTypeAddedConventions.Add(new KeyDiscoveryConvention(logger)); + conventions.EntityTypeAddedConventions.Add(new KeyDiscoveryConvention(dependencies)); - var keyConvention = new ValueGeneratorConvention(logger); + var keyConvention = new ValueGeneratorConvention(dependencies); conventions.ForeignKeyAddedConventions.Add(keyConvention); conventions.ForeignKeyRemovedConventions.Add(keyConvention); diff --git a/test/EFCore.Tests/Metadata/Internal/ClrCollectionAccessorFactoryTest.cs b/test/EFCore.Tests/Metadata/Internal/ClrCollectionAccessorFactoryTest.cs index 735b6400b90..c5332081522 100644 --- a/test/EFCore.Tests/Metadata/Internal/ClrCollectionAccessorFactoryTest.cs +++ b/test/EFCore.Tests/Metadata/Internal/ClrCollectionAccessorFactoryTest.cs @@ -8,8 +8,11 @@ using System.Reflection; using Microsoft.EntityFrameworkCore.Diagnostics; using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata.Conventions; +using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure; using Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal; using Microsoft.EntityFrameworkCore.TestUtilities; +using Microsoft.Extensions.DependencyInjection; using Xunit; // ReSharper disable UnassignedGetOnlyAutoProperty @@ -420,10 +423,13 @@ private void RunConvention(IMutableNavigation navigation) var context = new ConventionContext( ((ForeignKey)foreignKey).DeclaringEntityType.Model.ConventionDispatcher); - new BackingFieldConvention(new TestLogger()) + new BackingFieldConvention(CreateDependencies()) .ProcessNavigationAdded(((ForeignKey)foreignKey).Builder, (Navigation)navigation, context); } + private ProviderConventionSetBuilderDependencies CreateDependencies() + => InMemoryTestHelpers.Instance.CreateContextServices().GetRequiredService(); + private class MyEntity { private ICollection _asICollection; diff --git a/test/EFCore.Tests/Metadata/Internal/InternalModelBuilderTest.cs b/test/EFCore.Tests/Metadata/Internal/InternalModelBuilderTest.cs index 20033422c56..97d79a015b2 100644 --- a/test/EFCore.Tests/Metadata/Internal/InternalModelBuilderTest.cs +++ b/test/EFCore.Tests/Metadata/Internal/InternalModelBuilderTest.cs @@ -6,8 +6,11 @@ using System.Reflection; using Microsoft.EntityFrameworkCore.Diagnostics; using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Microsoft.EntityFrameworkCore.Metadata.Conventions; +using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure; using Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal; using Microsoft.EntityFrameworkCore.TestUtilities; +using Microsoft.Extensions.DependencyInjection; using Xunit; // ReSharper disable UnusedMember.Local @@ -344,11 +347,14 @@ public void Can_mark_type_as_owned_type() private static void Cleanup(InternalModelBuilder modelBuilder) { - new ModelCleanupConvention(new TestLogger()) + new ModelCleanupConvention(CreateDependencies()) .ProcessModelFinalized(modelBuilder, new ConventionContext(modelBuilder.Metadata.ConventionDispatcher)); } + private static ProviderConventionSetBuilderDependencies CreateDependencies() + => InMemoryTestHelpers.Instance.CreateContextServices().GetRequiredService(); + protected virtual InternalModelBuilder CreateModelBuilder(Model model = null) => new InternalModelBuilder(model ?? new Model()); diff --git a/test/EFCore.Tests/ModelBuilding/ShadowEntityTypeTest.cs b/test/EFCore.Tests/ModelBuilding/ShadowEntityTypeTest.cs index f13a8ab7c9c..b0691382195 100644 --- a/test/EFCore.Tests/ModelBuilding/ShadowEntityTypeTest.cs +++ b/test/EFCore.Tests/ModelBuilding/ShadowEntityTypeTest.cs @@ -6,7 +6,6 @@ using System.Linq; using Microsoft.EntityFrameworkCore.Diagnostics; using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Internal; using Microsoft.EntityFrameworkCore.TestUtilities; using Xunit; diff --git a/test/EFCore.Tests/ModelSourceTest.cs b/test/EFCore.Tests/ModelSourceTest.cs index 52b445f8041..8a65fee09e6 100644 --- a/test/EFCore.Tests/ModelSourceTest.cs +++ b/test/EFCore.Tests/ModelSourceTest.cs @@ -79,7 +79,7 @@ public void Adds_all_entities_based_on_all_distinct_entity_types_found() var logger = new TestLogger(); var model = CreateDefaultModelSource(setFinder) - .GetModel(InMemoryTestHelpers.Instance.CreateContext(), _nullConventionSetBuilder, new FakeModelValidator(), logger); + .GetModel(InMemoryTestHelpers.Instance.CreateContext(), _nullConventionSetBuilder); Assert.Equal( new[] { typeof(SetA).DisplayName(), typeof(SetB).DisplayName() }, @@ -95,7 +95,7 @@ public void Validate(IModel model, IDiagnosticsLogger FindSets(DbContext context) + public IReadOnlyList FindSets(Type contextType) => new[] { new DbSetProperty("One", typeof(SetA), setter: null), @@ -128,12 +128,12 @@ public void Caches_model_by_context_type() var modelSource = CreateDefaultModelSource(new DbSetFinder()); var logger = new TestLogger(); - var model1 = modelSource.GetModel(new Context1(), _nullConventionSetBuilder, _coreModelValidator, logger); - var model2 = modelSource.GetModel(new Context2(), _nullConventionSetBuilder, _coreModelValidator, logger); + var model1 = modelSource.GetModel(new Context1(), _nullConventionSetBuilder); + var model2 = modelSource.GetModel(new Context2(), _nullConventionSetBuilder); Assert.NotSame(model1, model2); - Assert.Same(model1, modelSource.GetModel(new Context1(), _nullConventionSetBuilder, _coreModelValidator, logger)); - Assert.Same(model2, modelSource.GetModel(new Context2(), _nullConventionSetBuilder, _coreModelValidator, logger)); + Assert.Same(model1, modelSource.GetModel(new Context1(), _nullConventionSetBuilder)); + Assert.Same(model2, modelSource.GetModel(new Context2(), _nullConventionSetBuilder)); } [Fact] @@ -142,7 +142,7 @@ public void Stores_model_version_information_as_annotation_on_model() var modelSource = CreateDefaultModelSource(new DbSetFinder()); var logger = new TestLogger(); - var model = modelSource.GetModel(new Context1(), _nullConventionSetBuilder, _coreModelValidator, logger); + var model = modelSource.GetModel(new Context1(), _nullConventionSetBuilder); var packageVersion = typeof(Context1).Assembly.GetCustomAttributes() .Single(m => m.Key == "PackageVersion").Value;