diff --git a/src/EFCore.Design/Design/Internal/DatabaseOperations.cs b/src/EFCore.Design/Design/Internal/DatabaseOperations.cs index 61f010af181..02a95b91383 100644 --- a/src/EFCore.Design/Design/Internal/DatabaseOperations.cs +++ b/src/EFCore.Design/Design/Internal/DatabaseOperations.cs @@ -62,7 +62,7 @@ public virtual Task ScaffoldContextAsync( loggerFactory.AddProvider(new LoggerProvider(categoryName => new OperationLogger(categoryName, _reporter))); #pragma warning restore CS0618 // Type or member is obsolete - var generator = services.GetRequiredService(); + var generator = services.GetRequiredService(); return generator.GenerateAsync( connectionString, diff --git a/src/EFCore.Design/Scaffolding/Internal/CSharpDbContextGenerator.cs b/src/EFCore.Design/Scaffolding/Internal/CSharpDbContextGenerator.cs index cae05b64a46..29088861c2b 100644 --- a/src/EFCore.Design/Scaffolding/Internal/CSharpDbContextGenerator.cs +++ b/src/EFCore.Design/Scaffolding/Internal/CSharpDbContextGenerator.cs @@ -20,11 +20,11 @@ namespace Microsoft.EntityFrameworkCore.Scaffolding.Internal /// This API supports the Entity Framework Core infrastructure and is not intended to be used /// directly from your code. This API may change or be removed in future releases. /// - public class CSharpDbContextGenerator + public class CSharpDbContextGenerator : ICSharpDbContextGenerator { private const string EntityLambdaIdentifier = "entity"; - private readonly CSharpUtilities _cSharpUtilities; + private readonly ICSharpUtilities _cSharpUtilities; private readonly IScaffoldingHelper _scaffoldingHelper; private readonly IAnnotationRenderer _annotationRenderer; private IndentedStringBuilder _sb; @@ -37,7 +37,7 @@ public class CSharpDbContextGenerator public CSharpDbContextGenerator( [NotNull] IScaffoldingHelper scaffoldingHelper, [NotNull] IAnnotationRenderer annotationRenderer, - [NotNull] CSharpUtilities cSharpUtilities) + [NotNull] ICSharpUtilities cSharpUtilities) { Check.NotNull(scaffoldingHelper, nameof(scaffoldingHelper)); Check.NotNull(annotationRenderer, nameof(annotationRenderer)); @@ -53,10 +53,10 @@ public CSharpDbContextGenerator( /// directly from your code. This API may change or be removed in future releases. /// public virtual string WriteCode( - [NotNull] IModel model, - [NotNull] string @namespace, - [NotNull] string contextName, - [NotNull] string connectionString, + IModel model, + string @namespace, + string contextName, + string connectionString, bool useDataAnnotations) { Check.NotNull(model, nameof(model)); diff --git a/src/EFCore.Design/Scaffolding/Internal/CSharpEntityTypeGenerator.cs b/src/EFCore.Design/Scaffolding/Internal/CSharpEntityTypeGenerator.cs index dab5f02ceb2..cf3b2f25bf5 100644 --- a/src/EFCore.Design/Scaffolding/Internal/CSharpEntityTypeGenerator.cs +++ b/src/EFCore.Design/Scaffolding/Internal/CSharpEntityTypeGenerator.cs @@ -19,9 +19,9 @@ namespace Microsoft.EntityFrameworkCore.Scaffolding.Internal /// This API supports the Entity Framework Core infrastructure and is not intended to be used /// directly from your code. This API may change or be removed in future releases. /// - public class CSharpEntityTypeGenerator + public class CSharpEntityTypeGenerator : ICSharpEntityTypeGenerator { - private CSharpUtilities CSharpUtilities { get; } + private ICSharpUtilities CSharpUtilities { get; } private IndentedStringBuilder _sb; private bool _useDataAnnotations; @@ -31,7 +31,7 @@ public class CSharpEntityTypeGenerator /// directly from your code. This API may change or be removed in future releases. /// public CSharpEntityTypeGenerator( - [NotNull] CSharpUtilities cSharpUtilities) + [NotNull] ICSharpUtilities cSharpUtilities) { Check.NotNull(cSharpUtilities, nameof(cSharpUtilities)); @@ -42,7 +42,7 @@ public CSharpEntityTypeGenerator( /// This API supports the Entity Framework Core infrastructure and is not intended to be used /// directly from your code. This API may change or be removed in future releases. /// - public virtual string WriteCode([NotNull] IEntityType entityType, [NotNull] string @namespace, bool useDataAnnotations) + public virtual string WriteCode(IEntityType entityType, string @namespace, bool useDataAnnotations) { Check.NotNull(entityType, nameof(entityType)); Check.NotNull(@namespace, nameof(@namespace)); diff --git a/src/EFCore.Design/Scaffolding/Internal/CSharpNamer.cs b/src/EFCore.Design/Scaffolding/Internal/CSharpNamer.cs index 70ed6618e29..a03ea37f288 100644 --- a/src/EFCore.Design/Scaffolding/Internal/CSharpNamer.cs +++ b/src/EFCore.Design/Scaffolding/Internal/CSharpNamer.cs @@ -15,7 +15,7 @@ namespace Microsoft.EntityFrameworkCore.Scaffolding.Internal public class CSharpNamer { private readonly Func _nameGetter; - private readonly CSharpUtilities _cSharpUtilities; + private readonly ICSharpUtilities _cSharpUtilities; /// /// This API supports the Entity Framework Core infrastructure and is not intended to be used @@ -27,12 +27,13 @@ public class CSharpNamer /// This API supports the Entity Framework Core infrastructure and is not intended to be used /// directly from your code. This API may change or be removed in future releases. /// - public CSharpNamer([NotNull] Func nameGetter) + public CSharpNamer([NotNull] Func nameGetter, [NotNull] ICSharpUtilities cSharpUtilities) { Check.NotNull(nameGetter, nameof(nameGetter)); + Check.NotNull(cSharpUtilities, nameof(cSharpUtilities)); _nameGetter = nameGetter; - _cSharpUtilities = new CSharpUtilities(); + _cSharpUtilities = cSharpUtilities; } /// diff --git a/src/EFCore.Design/Scaffolding/Internal/CSharpScaffoldingGenerator.cs b/src/EFCore.Design/Scaffolding/Internal/CSharpScaffoldingGenerator.cs index af35c946461..4a352ef44b1 100644 --- a/src/EFCore.Design/Scaffolding/Internal/CSharpScaffoldingGenerator.cs +++ b/src/EFCore.Design/Scaffolding/Internal/CSharpScaffoldingGenerator.cs @@ -20,13 +20,13 @@ public class CSharpScaffoldingGenerator : ScaffoldingCodeGenerator /// This API supports the Entity Framework Core infrastructure and is not intended to be used /// directly from your code. This API may change or be removed in future releases. /// - public virtual CSharpDbContextGenerator CSharpDbContextGenerator { get; } + public virtual ICSharpDbContextGenerator CSharpDbContextGenerator { get; } /// /// This API supports the Entity Framework Core infrastructure and is not intended to be used /// directly from your code. This API may change or be removed in future releases. /// - public virtual CSharpEntityTypeGenerator CSharpEntityTypeGenerator { get; } + public virtual ICSharpEntityTypeGenerator CSharpEntityTypeGenerator { get; } /// /// This API supports the Entity Framework Core infrastructure and is not intended to be used @@ -34,8 +34,8 @@ public class CSharpScaffoldingGenerator : ScaffoldingCodeGenerator /// public CSharpScaffoldingGenerator( [NotNull] IFileService fileService, - [NotNull] CSharpDbContextGenerator cSharpDbContextGenerator, - [NotNull] CSharpEntityTypeGenerator cSharpEntityTypeGenerator) + [NotNull] ICSharpDbContextGenerator cSharpDbContextGenerator, + [NotNull] ICSharpEntityTypeGenerator cSharpEntityTypeGenerator) : base(fileService) { Check.NotNull(cSharpDbContextGenerator, nameof(cSharpDbContextGenerator)); diff --git a/src/EFCore.Design/Scaffolding/Internal/CSharpUniqueNamer.cs b/src/EFCore.Design/Scaffolding/Internal/CSharpUniqueNamer.cs index b71972535ab..4617fe41e3f 100644 --- a/src/EFCore.Design/Scaffolding/Internal/CSharpUniqueNamer.cs +++ b/src/EFCore.Design/Scaffolding/Internal/CSharpUniqueNamer.cs @@ -19,8 +19,8 @@ public class CSharpUniqueNamer : CSharpNamer /// This API supports the Entity Framework Core infrastructure and is not intended to be used /// directly from your code. This API may change or be removed in future releases. /// - public CSharpUniqueNamer([NotNull] Func nameGetter) - : this(nameGetter, null) + public CSharpUniqueNamer([NotNull] Func nameGetter, [NotNull] ICSharpUtilities cSharpUtilities) + : this(nameGetter, null, cSharpUtilities) { } @@ -29,8 +29,9 @@ public CSharpUniqueNamer([NotNull] Func nameGetter) /// directly from your code. This API may change or be removed in future releases. /// public CSharpUniqueNamer([NotNull] Func nameGetter, - [CanBeNull] IEnumerable usedNames) - : base(nameGetter) + [CanBeNull] IEnumerable usedNames, + [NotNull] ICSharpUtilities cSharpUtilities) + : base(nameGetter, cSharpUtilities) { if (usedNames != null) { diff --git a/src/EFCore.Design/Scaffolding/Internal/CSharpUtilities.cs b/src/EFCore.Design/Scaffolding/Internal/CSharpUtilities.cs index a80e7c0ee23..1a2dae49715 100644 --- a/src/EFCore.Design/Scaffolding/Internal/CSharpUtilities.cs +++ b/src/EFCore.Design/Scaffolding/Internal/CSharpUtilities.cs @@ -16,7 +16,7 @@ namespace Microsoft.EntityFrameworkCore.Scaffolding.Internal /// This API supports the Entity Framework Core infrastructure and is not intended to be used /// directly from your code. This API may change or be removed in future releases. /// - public class CSharpUtilities + public class CSharpUtilities : ICSharpUtilities { private static readonly HashSet _cSharpKeywords = new HashSet { @@ -108,13 +108,7 @@ private static readonly Regex _invalidCharsRegex /// This API supports the Entity Framework Core infrastructure and is not intended to be used /// directly from your code. This API may change or be removed in future releases. /// - public static CSharpUtilities Instance { get; } = new CSharpUtilities(); - - /// - /// This API supports the Entity Framework Core infrastructure and is not intended to be used - /// directly from your code. This API may change or be removed in future releases. - /// - public virtual string DelimitString([NotNull] string value) + public virtual string DelimitString(string value) { Check.NotNull(value, nameof(value)); @@ -127,7 +121,7 @@ public virtual string DelimitString([NotNull] string value) /// This API supports the Entity Framework Core infrastructure and is not intended to be used /// directly from your code. This API may change or be removed in future releases. /// - public virtual string EscapeString([NotNull] string str) + public virtual string EscapeString(string str) { Check.NotNull(str, nameof(str)); @@ -138,7 +132,7 @@ public virtual string EscapeString([NotNull] string str) /// This API supports the Entity Framework Core infrastructure and is not intended to be used /// directly from your code. This API may change or be removed in future releases. /// - public virtual string EscapeVerbatimString([NotNull] string str) + public virtual string EscapeVerbatimString(string str) { Check.NotEmpty(str, nameof(str)); @@ -149,7 +143,7 @@ public virtual string EscapeVerbatimString([NotNull] string str) /// This API supports the Entity Framework Core infrastructure and is not intended to be used /// directly from your code. This API may change or be removed in future releases. /// - public virtual string GenerateLiteral([NotNull] byte[] value) + public virtual string GenerateLiteral(byte[] value) { Check.NotNull(value, nameof(value)); @@ -232,7 +226,7 @@ public virtual string GenerateLiteral(Guid value) /// This API supports the Entity Framework Core infrastructure and is not intended to be used /// directly from your code. This API may change or be removed in future releases. /// - public virtual string GenerateLiteral([NotNull] string value) + public virtual string GenerateLiteral(string value) { Check.NotNull(value, nameof(value)); @@ -243,7 +237,7 @@ public virtual string GenerateLiteral([NotNull] string value) /// This API supports the Entity Framework Core infrastructure and is not intended to be used /// directly from your code. This API may change or be removed in future releases. /// - public virtual string GenerateVerbatimStringLiteral([NotNull] string value) + public virtual string GenerateVerbatimStringLiteral(string value) { Check.NotNull(value, nameof(value)); @@ -254,7 +248,7 @@ public virtual string GenerateVerbatimStringLiteral([NotNull] string value) /// This API supports the Entity Framework Core infrastructure and is not intended to be used /// directly from your code. This API may change or be removed in future releases. /// - public virtual string GenerateLiteral([NotNull] object value) + public virtual string GenerateLiteral(object value) { Check.NotNull(value, nameof(value)); @@ -270,7 +264,7 @@ public virtual string GenerateLiteral([NotNull] object value) /// This API supports the Entity Framework Core infrastructure and is not intended to be used /// directly from your code. This API may change or be removed in future releases. /// - public virtual bool IsCSharpKeyword([NotNull] string identifier) + public virtual bool IsCSharpKeyword(string identifier) => _cSharpKeywords.Contains(identifier); /// @@ -278,7 +272,7 @@ public virtual bool IsCSharpKeyword([NotNull] string identifier) /// directly from your code. This API may change or be removed in future releases. /// public virtual string GenerateCSharpIdentifier( - [NotNull] string identifier, [CanBeNull] ICollection existingIdentifiers) + string identifier, [CanBeNull] ICollection existingIdentifiers) => GenerateCSharpIdentifier(identifier, existingIdentifiers, Uniquifier); /// @@ -286,8 +280,8 @@ public virtual string GenerateCSharpIdentifier( /// directly from your code. This API may change or be removed in future releases. /// public virtual string GenerateCSharpIdentifier( - [NotNull] string identifier, [CanBeNull] ICollection existingIdentifiers, - [NotNull] Func, string> uniquifier) + string identifier, [CanBeNull] ICollection existingIdentifiers, + Func, string> uniquifier) { Check.NotNull(identifier, nameof(identifier)); Check.NotNull(uniquifier, nameof(uniquifier)); @@ -321,7 +315,7 @@ public virtual string GenerateCSharpIdentifier( /// directly from your code. This API may change or be removed in future releases. /// public virtual string Uniquifier( - [NotNull] string proposedIdentifier, [CanBeNull] ICollection existingIdentifiers) + string proposedIdentifier, [CanBeNull] ICollection existingIdentifiers) { Check.NotEmpty(proposedIdentifier, nameof(proposedIdentifier)); @@ -364,7 +358,7 @@ public virtual string Uniquifier( /// This API supports the Entity Framework Core infrastructure and is not intended to be used /// directly from your code. This API may change or be removed in future releases. /// - public virtual string GetTypeName([NotNull] Type type) + public virtual string GetTypeName(Type type) { Check.NotNull(type, nameof(type)); diff --git a/src/EFCore.Design/Scaffolding/Internal/CandidateNamingService.cs b/src/EFCore.Design/Scaffolding/Internal/CandidateNamingService.cs index 9f40e13ecfe..1c724bda6b3 100644 --- a/src/EFCore.Design/Scaffolding/Internal/CandidateNamingService.cs +++ b/src/EFCore.Design/Scaffolding/Internal/CandidateNamingService.cs @@ -5,7 +5,6 @@ using System.Collections.Generic; using System.Linq; using System.Text; -using JetBrains.Annotations; using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Metadata.Internal; using Microsoft.EntityFrameworkCore.Utilities; @@ -16,13 +15,13 @@ namespace Microsoft.EntityFrameworkCore.Scaffolding.Internal /// This API supports the Entity Framework Core infrastructure and is not intended to be used /// directly from your code. This API may change or be removed in future releases. /// - public class CandidateNamingService + public class CandidateNamingService : ICandidateNamingService { /// /// This API supports the Entity Framework Core infrastructure and is not intended to be used /// directly from your code. This API may change or be removed in future releases. /// - public virtual string GenerateCandidateIdentifier([NotNull] string originalIdentifier) + public virtual string GenerateCandidateIdentifier(string originalIdentifier) { Check.NotEmpty(originalIdentifier, nameof(originalIdentifier)); @@ -59,7 +58,7 @@ public virtual string GenerateCandidateIdentifier([NotNull] string originalIdent /// This API supports the Entity Framework Core infrastructure and is not intended to be used /// directly from your code. This API may change or be removed in future releases. /// - public virtual string GetDependentEndCandidateNavigationPropertyName([NotNull] IForeignKey foreignKey) + public virtual string GetDependentEndCandidateNavigationPropertyName(IForeignKey foreignKey) { Check.NotNull(foreignKey, nameof(foreignKey)); @@ -78,8 +77,8 @@ public virtual string GetDependentEndCandidateNavigationPropertyName([NotNull] I /// directly from your code. This API may change or be removed in future releases. /// public virtual string GetPrincipalEndCandidateNavigationPropertyName( - [NotNull] IForeignKey foreignKey, - [NotNull] string dependentEndNavigationPropertyName) + IForeignKey foreignKey, + string dependentEndNavigationPropertyName) { Check.NotNull(foreignKey, nameof(foreignKey)); Check.NotEmpty(dependentEndNavigationPropertyName, nameof(dependentEndNavigationPropertyName)); diff --git a/src/EFCore.Design/Scaffolding/Internal/ICSharpDbContextGenerator.cs b/src/EFCore.Design/Scaffolding/Internal/ICSharpDbContextGenerator.cs new file mode 100644 index 00000000000..3846c240b6b --- /dev/null +++ b/src/EFCore.Design/Scaffolding/Internal/ICSharpDbContextGenerator.cs @@ -0,0 +1,18 @@ +// 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.Metadata; + +namespace Microsoft.EntityFrameworkCore.Scaffolding.Internal +{ + public interface ICSharpDbContextGenerator + { + string WriteCode( + [NotNull] IModel model, + [NotNull] string @namespace, + [NotNull] string contextName, + [NotNull] string connectionString, + bool useDataAnnotations); + } +} \ No newline at end of file diff --git a/src/EFCore.Design/Scaffolding/Internal/ICSharpEntityTypeGenerator.cs b/src/EFCore.Design/Scaffolding/Internal/ICSharpEntityTypeGenerator.cs new file mode 100644 index 00000000000..422b82faa43 --- /dev/null +++ b/src/EFCore.Design/Scaffolding/Internal/ICSharpEntityTypeGenerator.cs @@ -0,0 +1,13 @@ +// 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.Metadata; + +namespace Microsoft.EntityFrameworkCore.Scaffolding.Internal +{ + public interface ICSharpEntityTypeGenerator + { + string WriteCode([NotNull] IEntityType entityType, [NotNull] string @namespace, bool useDataAnnotations); + } +} \ No newline at end of file diff --git a/src/EFCore.Design/Scaffolding/Internal/ICSharpUtilities.cs b/src/EFCore.Design/Scaffolding/Internal/ICSharpUtilities.cs new file mode 100644 index 00000000000..f07ddc3c11d --- /dev/null +++ b/src/EFCore.Design/Scaffolding/Internal/ICSharpUtilities.cs @@ -0,0 +1,36 @@ +// 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; + +namespace Microsoft.EntityFrameworkCore.Scaffolding.Internal +{ + public interface ICSharpUtilities + { + string DelimitString([NotNull] string value); + string EscapeString([NotNull] string str); + string EscapeVerbatimString([NotNull] string str); + string GenerateCSharpIdentifier([NotNull] string identifier, [CanBeNull] ICollection existingIdentifiers); + string GenerateCSharpIdentifier([NotNull] string identifier, [CanBeNull] ICollection existingIdentifiers, [NotNull] Func, string> uniquifier); + string GenerateLiteral(bool value); + string GenerateLiteral([NotNull] byte[] value); + string GenerateLiteral(DateTime value); + string GenerateLiteral(DateTimeOffset value); + string GenerateLiteral(decimal value); + string GenerateLiteral(double value); + string GenerateLiteral(float value); + string GenerateLiteral(Guid value); + string GenerateLiteral(int value); + string GenerateLiteral(long value); + string GenerateLiteral([NotNull] object value); + string GenerateLiteral([NotNull] string value); + string GenerateLiteral(TimeSpan value); + string GenerateVerbatimStringLiteral([NotNull] string value); + string GetTypeName([NotNull] Type type); + bool IsCSharpKeyword([NotNull] string identifier); + bool IsValidIdentifier([CanBeNull] string name); + string Uniquifier([NotNull] string proposedIdentifier, [CanBeNull] ICollection existingIdentifiers); + } +} \ No newline at end of file diff --git a/src/EFCore.Design/Scaffolding/Internal/ICandidateNamingService.cs b/src/EFCore.Design/Scaffolding/Internal/ICandidateNamingService.cs new file mode 100644 index 00000000000..82a20199797 --- /dev/null +++ b/src/EFCore.Design/Scaffolding/Internal/ICandidateNamingService.cs @@ -0,0 +1,18 @@ +// 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.Metadata; + +namespace Microsoft.EntityFrameworkCore.Scaffolding.Internal +{ + public interface ICandidateNamingService + { + string GenerateCandidateIdentifier([NotNull] string originalIdentifier); + string GetDependentEndCandidateNavigationPropertyName([NotNull] IForeignKey foreignKey); + + string GetPrincipalEndCandidateNavigationPropertyName( + [NotNull] IForeignKey foreignKey, + [NotNull] string dependentEndNavigationPropertyName); + } +} \ No newline at end of file diff --git a/src/EFCore.Design/Scaffolding/Internal/IModelScaffolder.cs b/src/EFCore.Design/Scaffolding/Internal/IModelScaffolder.cs new file mode 100644 index 00000000000..898659e6d16 --- /dev/null +++ b/src/EFCore.Design/Scaffolding/Internal/IModelScaffolder.cs @@ -0,0 +1,23 @@ +// 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.Threading; +using System.Threading.Tasks; +using JetBrains.Annotations; + +namespace Microsoft.EntityFrameworkCore.Scaffolding.Internal +{ + public interface IModelScaffolder + { + Task GenerateAsync( + [NotNull] string connectionString, + [NotNull] TableSelectionSet tableSelectionSet, + [NotNull] string projectPath, + [CanBeNull] string outputPath, + [NotNull] string rootNamespace, + [CanBeNull] string contextName, + bool useDataAnnotations, + bool overwriteFiles, + CancellationToken cancellationToken = default(CancellationToken)); + } +} diff --git a/src/EFCore.Design/Scaffolding/Internal/IScaffoldingCodeGenerator.cs b/src/EFCore.Design/Scaffolding/Internal/IScaffoldingCodeGenerator.cs new file mode 100644 index 00000000000..1ff34fa564b --- /dev/null +++ b/src/EFCore.Design/Scaffolding/Internal/IScaffoldingCodeGenerator.cs @@ -0,0 +1,36 @@ +// 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.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; +using JetBrains.Annotations; +using Microsoft.EntityFrameworkCore.Metadata; + +namespace Microsoft.EntityFrameworkCore.Scaffolding.Internal +{ + public interface IScaffoldingCodeGenerator + { + string FileExtension { get; } + IFileService FileService { get; } + + IList GetExistingFilePaths( + [NotNull] string outputPath, + [NotNull] string dbContextClassName, + [NotNull] IEnumerable entityTypes); + + IList GetReadOnlyFilePaths( + [NotNull] string outputPath, + [NotNull] string dbContextClassName, + [NotNull] IEnumerable entityTypes); + + Task WriteCodeAsync( + [NotNull] IModel model, + [NotNull] string outputPath, + [NotNull] string @namespace, + [NotNull] string contextName, + [NotNull] string connectionString, + bool dataAnnotations, + CancellationToken cancellationToken = default(CancellationToken)); + } +} \ No newline at end of file diff --git a/src/EFCore.Design/Scaffolding/Internal/ModelScaffolder.cs b/src/EFCore.Design/Scaffolding/Internal/ModelScaffolder.cs index 34bb94b7cae..d5d4fd004da 100644 --- a/src/EFCore.Design/Scaffolding/Internal/ModelScaffolder.cs +++ b/src/EFCore.Design/Scaffolding/Internal/ModelScaffolder.cs @@ -18,10 +18,10 @@ namespace Microsoft.EntityFrameworkCore.Scaffolding.Internal /// This API supports the Entity Framework Core infrastructure and is not intended to be used /// directly from your code. This API may change or be removed in future releases. /// - public class ModelScaffolder + public class ModelScaffolder : IModelScaffolder { private readonly IScaffoldingModelFactory _factory; - private readonly CSharpUtilities _cSharpUtilities; + private readonly ICSharpUtilities _cSharpUtilities; private static readonly char[] _directorySeparatorChars = { Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar }; private const string DbContextSuffix = "Context"; private const string DefaultDbContextName = "Model" + DbContextSuffix; @@ -32,8 +32,8 @@ public class ModelScaffolder /// public ModelScaffolder( [NotNull] IScaffoldingModelFactory scaffoldingModelFactory, - [NotNull] ScaffoldingCodeGenerator scaffoldingCodeGenerator, - [NotNull] CSharpUtilities cSharpUtilities) + [NotNull] IScaffoldingCodeGenerator scaffoldingCodeGenerator, + [NotNull] ICSharpUtilities cSharpUtilities) { Check.NotNull(scaffoldingModelFactory, nameof(scaffoldingModelFactory)); Check.NotNull(scaffoldingCodeGenerator, nameof(scaffoldingCodeGenerator)); @@ -47,19 +47,19 @@ public ModelScaffolder( /// This API supports the Entity Framework Core infrastructure and is not intended to be used /// directly from your code. This API may change or be removed in future releases. /// - private ScaffoldingCodeGenerator ScaffoldingCodeGenerator { get; } + private IScaffoldingCodeGenerator ScaffoldingCodeGenerator { get; } /// /// This API supports the Entity Framework Core infrastructure and is not intended to be used /// directly from your code. This API may change or be removed in future releases. /// public virtual Task GenerateAsync( - [NotNull] string connectionString, - [NotNull] TableSelectionSet tableSelectionSet, - [NotNull] string projectPath, - [CanBeNull] string outputPath, - [NotNull] string rootNamespace, - [CanBeNull] string contextName, + string connectionString, + TableSelectionSet tableSelectionSet, + string projectPath, + string outputPath, + string rootNamespace, + string contextName, bool useDataAnnotations, bool overwriteFiles, CancellationToken cancellationToken = default(CancellationToken)) diff --git a/src/EFCore.Design/Scaffolding/Internal/RelationalScaffoldingModelFactory.cs b/src/EFCore.Design/Scaffolding/Internal/RelationalScaffoldingModelFactory.cs index 128bf0e5a6f..9157b2e1466 100644 --- a/src/EFCore.Design/Scaffolding/Internal/RelationalScaffoldingModelFactory.cs +++ b/src/EFCore.Design/Scaffolding/Internal/RelationalScaffoldingModelFactory.cs @@ -15,7 +15,6 @@ using Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal; using Microsoft.EntityFrameworkCore.Metadata.Internal; using Microsoft.EntityFrameworkCore.Migrations; -using Microsoft.EntityFrameworkCore.Scaffolding.Internal; using Microsoft.EntityFrameworkCore.Scaffolding.Metadata; using Microsoft.EntityFrameworkCore.Storage; using Microsoft.EntityFrameworkCore.Utilities; @@ -29,7 +28,7 @@ public class RelationalScaffoldingModelFactory : IScaffoldingModelFactory protected virtual IDiagnosticsLogger Logger { get; } protected virtual IRelationalTypeMapper TypeMapper { get; } - protected virtual CandidateNamingService CandidateNamingService { get; } + protected virtual ICandidateNamingService CandidateNamingService { get; } private Dictionary> _columnNamers; private readonly TableModel _nullTable = new TableModel(); @@ -38,20 +37,23 @@ public class RelationalScaffoldingModelFactory : IScaffoldingModelFactory private readonly HashSet _unmappedColumns = new HashSet(); private readonly IPluralizer _pluralizer; private readonly IScaffoldingHelper _scaffoldingHelper; + private readonly ICSharpUtilities _cSharpUtilities; public RelationalScaffoldingModelFactory( [NotNull] IDiagnosticsLogger logger, [NotNull] IRelationalTypeMapper typeMapper, [NotNull] IDatabaseModelFactory databaseModelFactory, - [NotNull] CandidateNamingService candidateNamingService, + [NotNull] ICandidateNamingService candidateNamingService, [NotNull] IPluralizer pluralizer, - [NotNull] IScaffoldingHelper scaffoldingHelper) + [NotNull] IScaffoldingHelper scaffoldingHelper, + [NotNull] ICSharpUtilities cSharpUtilities) { Check.NotNull(logger, nameof(logger)); Check.NotNull(typeMapper, nameof(typeMapper)); Check.NotNull(databaseModelFactory, nameof(databaseModelFactory)); Check.NotNull(candidateNamingService, nameof(candidateNamingService)); Check.NotNull(pluralizer, nameof(pluralizer)); + Check.NotNull(cSharpUtilities, nameof(cSharpUtilities)); Logger = logger; TypeMapper = typeMapper; @@ -59,6 +61,7 @@ public RelationalScaffoldingModelFactory( _databaseModelFactory = databaseModelFactory; _pluralizer = pluralizer; _scaffoldingHelper = scaffoldingHelper; + _cSharpUtilities = cSharpUtilities; } public virtual IModel Create(string connectionString, TableSelectionSet tableSelectionSet) @@ -93,7 +96,9 @@ protected virtual IModel CreateFromDatabaseModel([NotNull] DatabaseModel databas var modelBuilder = new ModelBuilder(new ConventionSet()); - _tableNamer = new CSharpUniqueNamer(t => CandidateNamingService.GenerateCandidateIdentifier(t.Name)); + _tableNamer = new CSharpUniqueNamer( + t => CandidateNamingService.GenerateCandidateIdentifier(t.Name), + _cSharpUtilities); _columnNamers = new Dictionary>(); VisitDatabaseModel(modelBuilder, databaseModel); @@ -124,7 +129,7 @@ protected virtual string GetPropertyName([NotNull] ColumnModel column) _columnNamers.Add( table, new CSharpUniqueNamer( - c => CandidateNamingService.GenerateCandidateIdentifier(c.Name), usedNames)); + c => CandidateNamingService.GenerateCandidateIdentifier(c.Name), usedNames, _cSharpUtilities)); } return _columnNamers[table].GetName(column); @@ -631,7 +636,7 @@ protected virtual void AddNavigationProperties([NotNull] IMutableForeignKey fore var dependentEndNavigationPropertyCandidateName = CandidateNamingService.GetDependentEndCandidateNavigationPropertyName(foreignKey); var dependentEndNavigationPropertyName = - CSharpUtilities.Instance.GenerateCSharpIdentifier( + _cSharpUtilities.GenerateCSharpIdentifier( dependentEndNavigationPropertyCandidateName, dependentEndExistingIdentifiers, NavigationUniquifier); @@ -654,7 +659,7 @@ protected virtual void AddNavigationProperties([NotNull] IMutableForeignKey fore } var principalEndNavigationPropertyName = - CSharpUtilities.Instance.GenerateCSharpIdentifier( + _cSharpUtilities.GenerateCSharpIdentifier( principalEndNavigationPropertyCandidateName, principalEndExistingIdentifiers, NavigationUniquifier); diff --git a/src/EFCore.Design/Scaffolding/Internal/ScaffoldingCodeGenerator.cs b/src/EFCore.Design/Scaffolding/Internal/ScaffoldingCodeGenerator.cs index 2add1e9d736..7c4c0b950b4 100644 --- a/src/EFCore.Design/Scaffolding/Internal/ScaffoldingCodeGenerator.cs +++ b/src/EFCore.Design/Scaffolding/Internal/ScaffoldingCodeGenerator.cs @@ -16,7 +16,7 @@ namespace Microsoft.EntityFrameworkCore.Scaffolding.Internal /// This API supports the Entity Framework Core infrastructure and is not intended to be used /// directly from your code. This API may change or be removed in future releases. /// - public abstract class ScaffoldingCodeGenerator + public abstract class ScaffoldingCodeGenerator : IScaffoldingCodeGenerator { /// /// This API supports the Entity Framework Core infrastructure and is not intended to be used diff --git a/src/EFCore.Design/Scaffolding/Internal/ScaffoldingServiceCollectionExtensions.cs b/src/EFCore.Design/Scaffolding/Internal/ScaffoldingServiceCollectionExtensions.cs index cdfff3c0cf3..823c92f4300 100644 --- a/src/EFCore.Design/Scaffolding/Internal/ScaffoldingServiceCollectionExtensions.cs +++ b/src/EFCore.Design/Scaffolding/Internal/ScaffoldingServiceCollectionExtensions.cs @@ -6,9 +6,9 @@ using Microsoft.EntityFrameworkCore.Design; using Microsoft.EntityFrameworkCore.Design.Internal; using Microsoft.EntityFrameworkCore.Diagnostics; +using Microsoft.EntityFrameworkCore.Internal; using Microsoft.EntityFrameworkCore.Storage; using Microsoft.Extensions.DependencyInjection; -using Microsoft.EntityFrameworkCore.Internal; namespace Microsoft.EntityFrameworkCore.Scaffolding.Internal { @@ -23,16 +23,19 @@ public static class ScaffoldingServiceCollectionExtensions /// directly from your code. This API may change or be removed in future releases. /// public static IServiceCollection AddScaffolding([NotNull] this IServiceCollection serviceCollection) - => serviceCollection.AddSingleton() + => serviceCollection + .AddSingleton() + .AddSingleton() .AddSingleton() - .AddSingleton() - .AddSingleton() + .AddSingleton() + .AddSingleton() .AddSingleton() - .AddSingleton() - .AddSingleton() - .AddSingleton() - .AddSingleton() - .AddSingleton() + .AddSingleton() + .AddSingleton() + .AddSingleton() + .AddSingleton() + .AddSingleton() + .AddSingleton() .AddSingleton() .AddSingleton() .AddSingleton(new DiagnosticListener(DbLoggerCategory.Name)) diff --git a/src/EFCore.Relational.Design.Specification.Tests/ReverseEngineering/E2ETestBase.cs b/src/EFCore.Relational.Design.Specification.Tests/ReverseEngineering/E2ETestBase.cs index 67569f968e6..31a0c5e1d5f 100644 --- a/src/EFCore.Relational.Design.Specification.Tests/ReverseEngineering/E2ETestBase.cs +++ b/src/EFCore.Relational.Design.Specification.Tests/ReverseEngineering/E2ETestBase.cs @@ -21,7 +21,7 @@ public abstract class E2ETestBase private readonly ITestOutputHelper _output; protected InMemoryOperationReporter _reporter; protected InMemoryFileService InMemoryFiles; - protected readonly ModelScaffolder Generator; + protected readonly IModelScaffolder Generator; protected readonly IScaffoldingModelFactory ScaffoldingModelFactory; protected E2ETestBase(ITestOutputHelper output) @@ -44,7 +44,7 @@ protected E2ETestBase(ITestOutputHelper output) factory.AddProvider(new LoggerProvider(categoryName => new OperationLogger(categoryName, _reporter))); #pragma warning restore CS0618 // Type or member is obsolete - Generator = serviceProvider.GetRequiredService(); + Generator = serviceProvider.GetRequiredService(); ScaffoldingModelFactory = serviceProvider.GetRequiredService(); } diff --git a/src/EFCore.Relational/Design/AnnotationRendererBase.cs b/src/EFCore.Relational/Design/AnnotationRendererBase.cs index 7b73eb9d78a..7a417f3d97f 100644 --- a/src/EFCore.Relational/Design/AnnotationRendererBase.cs +++ b/src/EFCore.Relational/Design/AnnotationRendererBase.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 JetBrains.Annotations; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Utilities; @@ -9,6 +10,15 @@ namespace Microsoft.EntityFrameworkCore.Design { public class AnnotationRendererBase : IAnnotationRenderer { + public AnnotationRendererBase([NotNull] AnnotationRendererDependencies dependencies) + { + Check.NotNull(dependencies, nameof(dependencies)); + + Dependencies = dependencies; + } + + protected virtual AnnotationRendererDependencies Dependencies { get; } + public virtual bool IsHandledByConvention(IModel model, IAnnotation annotation) { Check.NotNull(model, nameof(model)); diff --git a/src/EFCore.Relational/Design/AnnotationRendererDependencies.cs b/src/EFCore.Relational/Design/AnnotationRendererDependencies.cs new file mode 100644 index 00000000000..d63f26cb0ee --- /dev/null +++ b/src/EFCore.Relational/Design/AnnotationRendererDependencies.cs @@ -0,0 +1,9 @@ +// 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.Design +{ + public sealed class AnnotationRendererDependencies + { + } +} diff --git a/src/EFCore.Relational/Scaffolding/IScaffoldingTypeMapper.cs b/src/EFCore.Relational/Scaffolding/IScaffoldingTypeMapper.cs new file mode 100644 index 00000000000..348e03a3b3e --- /dev/null +++ b/src/EFCore.Relational/Scaffolding/IScaffoldingTypeMapper.cs @@ -0,0 +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 JetBrains.Annotations; + +namespace Microsoft.EntityFrameworkCore.Scaffolding +{ + public interface IScaffoldingTypeMapper + { + TypeScaffoldingInfo FindMapping([NotNull] string storeType, bool keyOrIndex, bool rowVersion); + } +} \ No newline at end of file diff --git a/src/EFCore.Relational/Scaffolding/ScaffoldingTypeMapper.cs b/src/EFCore.Relational/Scaffolding/ScaffoldingTypeMapper.cs index 6fd0c670f08..6c3cb90ab30 100644 --- a/src/EFCore.Relational/Scaffolding/ScaffoldingTypeMapper.cs +++ b/src/EFCore.Relational/Scaffolding/ScaffoldingTypeMapper.cs @@ -8,16 +8,16 @@ namespace Microsoft.EntityFrameworkCore.Scaffolding { - public class ScaffoldingTypeMapper + public class ScaffoldingTypeMapper : IScaffoldingTypeMapper { - public ScaffoldingTypeMapper([NotNull] IRelationalTypeMapper typeMapper) + public ScaffoldingTypeMapper([NotNull] ScaffoldingTypeMapperDependencies dependencies) { - Check.NotNull(typeMapper, nameof(typeMapper)); + Check.NotNull(dependencies, nameof(dependencies)); - TypeMapper = typeMapper; + Dependencies = dependencies; } - protected virtual IRelationalTypeMapper TypeMapper { get; } + protected virtual ScaffoldingTypeMapperDependencies Dependencies { get; } public virtual TypeScaffoldingInfo FindMapping( [NotNull] string storeType, @@ -27,7 +27,7 @@ public virtual TypeScaffoldingInfo FindMapping( // This is because certain providers can have no type specified as a default type e.g. SQLite Check.NotNull(storeType, nameof(storeType)); - var mapping = TypeMapper.FindMapping(storeType); + var mapping = Dependencies.TypeMapper.FindMapping(storeType); if (mapping == null) { return null; @@ -38,42 +38,42 @@ public virtual TypeScaffoldingInfo FindMapping( int? scaffoldMaxLengh = null; if (mapping.ClrType == typeof(byte[]) - && TypeMapper.ByteArrayMapper != null) + && Dependencies.TypeMapper.ByteArrayMapper != null) { // Check for inference - var byteArrayMapping = TypeMapper.ByteArrayMapper.FindMapping(rowVersion, keyOrIndex, mapping.Size); + var byteArrayMapping = Dependencies.TypeMapper.ByteArrayMapper.FindMapping(rowVersion, keyOrIndex, mapping.Size); if (byteArrayMapping.StoreType.Equals(storeType, StringComparison.OrdinalIgnoreCase)) { canInfer = true; // Check for size - var sizedMapping = TypeMapper.ByteArrayMapper.FindMapping(rowVersion, keyOrIndex, size: null); + var sizedMapping = Dependencies.TypeMapper.ByteArrayMapper.FindMapping(rowVersion, keyOrIndex, size: null); scaffoldMaxLengh = sizedMapping.Size != byteArrayMapping.Size ? byteArrayMapping.Size : null; } } else if (mapping.ClrType == typeof(string) - && TypeMapper.StringMapper != null) + && Dependencies.TypeMapper.StringMapper != null) { // Check for inference - var stringMapping = TypeMapper.StringMapper.FindMapping(mapping.IsUnicode, keyOrIndex, mapping.Size); + var stringMapping = Dependencies.TypeMapper.StringMapper.FindMapping(mapping.IsUnicode, keyOrIndex, mapping.Size); if (stringMapping.StoreType.Equals(storeType, StringComparison.OrdinalIgnoreCase)) { canInfer = true; // Check for unicode - var unicodeMapping = TypeMapper.StringMapper.FindMapping(unicode: true, keyOrIndex: keyOrIndex, maxLength: mapping.Size); + var unicodeMapping = Dependencies.TypeMapper.StringMapper.FindMapping(unicode: true, keyOrIndex: keyOrIndex, maxLength: mapping.Size); scaffoldUnicode = unicodeMapping.IsUnicode != stringMapping.IsUnicode ? (bool?)stringMapping.IsUnicode : null; // Check for size - var sizedMapping = TypeMapper.StringMapper.FindMapping(unicode: mapping.IsUnicode, keyOrIndex: keyOrIndex, maxLength: null); + var sizedMapping = Dependencies.TypeMapper.StringMapper.FindMapping(unicode: mapping.IsUnicode, keyOrIndex: keyOrIndex, maxLength: null); scaffoldMaxLengh = sizedMapping.Size != stringMapping.Size ? stringMapping.Size : null; } } else { - var defaultMapping = TypeMapper.GetMapping(mapping.ClrType); + var defaultMapping = Dependencies.TypeMapper.GetMapping(mapping.ClrType); if (defaultMapping.StoreType.Equals(storeType, StringComparison.OrdinalIgnoreCase)) { diff --git a/src/EFCore.Relational/Scaffolding/ScaffoldingTypeMapperDependencies.cs b/src/EFCore.Relational/Scaffolding/ScaffoldingTypeMapperDependencies.cs new file mode 100644 index 00000000000..72d8be2711e --- /dev/null +++ b/src/EFCore.Relational/Scaffolding/ScaffoldingTypeMapperDependencies.cs @@ -0,0 +1,68 @@ +// 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; + +namespace Microsoft.EntityFrameworkCore.Scaffolding +{ + /// + /// + /// Service dependencies parameter class for + /// + /// + /// This type is typically used by database providers (and other extensions). It is generally + /// not used in application code. + /// + /// + /// Do not construct instances of this class directly from either provider or application code as the + /// constructor signature may change as new dependencies are added. Instead, use this type in + /// your constructor so that an instance will be created and injected automatically by the + /// dependency injection container. To create an instance with some dependent services replaced, + /// first resolve the object from the dependency injection container, then replace selected + /// services using the 'With...' methods. Do not call the constructor at any point in this process. + /// + /// + public sealed class ScaffoldingTypeMapperDependencies + { + /// + /// + /// Creates the service dependencies parameter object for a . + /// + /// + /// Do not call this constructor directly from either provider or application code as it may change + /// as new dependencies are added. Instead, use this type in your constructor so that an instance + /// will be created and injected automatically by the dependency injection container. To create + /// an instance with some dependent services replaced, first resolve the object from the dependency + /// injection container, then replace selected services using the 'With...' methods. Do not call + /// the constructor at any point in this process. + /// + /// + /// This API supports the Entity Framework Core infrastructure and is not intended to be used + /// directly from your code. This API may change or be removed in future releases. + /// + /// + /// The type mapper. + public ScaffoldingTypeMapperDependencies([NotNull] IRelationalTypeMapper typeMapper) + { + Check.NotNull(typeMapper, nameof(typeMapper)); + + TypeMapper = typeMapper; + } + + /// + /// The type mapper. + /// + public IRelationalTypeMapper TypeMapper { 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 ScaffoldingTypeMapperDependencies With([NotNull] IRelationalTypeMapper typeMapper) + => new ScaffoldingTypeMapperDependencies( + typeMapper); + } +} diff --git a/src/EFCore.SqlServer/Design/Internal/SqlServerAnnotationRenderer.cs b/src/EFCore.SqlServer/Design/Internal/SqlServerAnnotationRenderer.cs index 4d413c5ad6f..4f3573ba246 100644 --- a/src/EFCore.SqlServer/Design/Internal/SqlServerAnnotationRenderer.cs +++ b/src/EFCore.SqlServer/Design/Internal/SqlServerAnnotationRenderer.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 JetBrains.Annotations; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Metadata.Internal; @@ -11,6 +12,11 @@ namespace Microsoft.EntityFrameworkCore.Design.Internal { public class SqlServerAnnotationRenderer : AnnotationRendererBase { + public SqlServerAnnotationRenderer([NotNull] AnnotationRendererDependencies dependencies) + : base(dependencies) + { + } + public override bool IsHandledByConvention(IModel model, IAnnotation annotation) { Check.NotNull(model, nameof(model)); diff --git a/src/EFCore.SqlServer/Scaffolding/Internal/SqlServerScaffoldingHelper.cs b/src/EFCore.SqlServer/Scaffolding/Internal/SqlServerScaffoldingHelper.cs index 66b22001e27..53ee6bb2593 100644 --- a/src/EFCore.SqlServer/Scaffolding/Internal/SqlServerScaffoldingHelper.cs +++ b/src/EFCore.SqlServer/Scaffolding/Internal/SqlServerScaffoldingHelper.cs @@ -10,9 +10,9 @@ namespace Microsoft.EntityFrameworkCore.Scaffolding.Internal { public class SqlServerScaffoldingHelper : IScaffoldingHelper { - private readonly ScaffoldingTypeMapper _scaffoldingTypeMapper; + private readonly IScaffoldingTypeMapper _scaffoldingTypeMapper; - public SqlServerScaffoldingHelper([NotNull] ScaffoldingTypeMapper scaffoldingTypeMapper) + public SqlServerScaffoldingHelper([NotNull] IScaffoldingTypeMapper scaffoldingTypeMapper) { Check.NotNull(scaffoldingTypeMapper, nameof(scaffoldingTypeMapper)); diff --git a/src/EFCore.Sqlite.Core/Scaffolding/Internal/SqliteScaffoldingHelper.cs b/src/EFCore.Sqlite.Core/Scaffolding/Internal/SqliteScaffoldingHelper.cs index 81d94eac6e8..03077d299dc 100644 --- a/src/EFCore.Sqlite.Core/Scaffolding/Internal/SqliteScaffoldingHelper.cs +++ b/src/EFCore.Sqlite.Core/Scaffolding/Internal/SqliteScaffoldingHelper.cs @@ -9,9 +9,9 @@ namespace Microsoft.EntityFrameworkCore.Scaffolding.Internal { public class SqliteScaffoldingHelper : IScaffoldingHelper { - private readonly ScaffoldingTypeMapper _scaffoldingTypeMapper; + private readonly IScaffoldingTypeMapper _scaffoldingTypeMapper; - public SqliteScaffoldingHelper([NotNull] ScaffoldingTypeMapper scaffoldingTypeMapper) + public SqliteScaffoldingHelper([NotNull] IScaffoldingTypeMapper scaffoldingTypeMapper) { Check.NotNull(scaffoldingTypeMapper, nameof(scaffoldingTypeMapper)); diff --git a/test/EFCore.Design.Tests/Scaffolding/Internal/CSharpNamerTest.cs b/test/EFCore.Design.Tests/Scaffolding/Internal/CSharpNamerTest.cs index 6504c73a9a4..0d5563bb623 100644 --- a/test/EFCore.Design.Tests/Scaffolding/Internal/CSharpNamerTest.cs +++ b/test/EFCore.Design.Tests/Scaffolding/Internal/CSharpNamerTest.cs @@ -15,7 +15,7 @@ public class CSharpNamerTest [InlineData("8ball", "_8ball")] public void Sanitizes_name(string input, string output) { - Assert.Equal(output, new CSharpNamer(s => s).GetName(input)); + Assert.Equal(output, new CSharpNamer(s => s, new CSharpUtilities()).GetName(input)); } } } diff --git a/test/EFCore.Design.Tests/Scaffolding/Internal/CSharpUniqueNamerTest.cs b/test/EFCore.Design.Tests/Scaffolding/Internal/CSharpUniqueNamerTest.cs index 025f0749165..c18bf408d65 100644 --- a/test/EFCore.Design.Tests/Scaffolding/Internal/CSharpUniqueNamerTest.cs +++ b/test/EFCore.Design.Tests/Scaffolding/Internal/CSharpUniqueNamerTest.cs @@ -12,7 +12,7 @@ public class CSharpUniqueNamerTest [Fact] public void Returns_unique_name_for_type() { - var namer = new CSharpUniqueNamer(s => s.Name); + var namer = new CSharpUniqueNamer(s => s.Name, new CSharpUtilities()); var input1 = new ColumnModel { Name = "Id" @@ -31,7 +31,7 @@ public void Returns_unique_name_for_type() [Fact] public void Uses_comparer() { - var namer = new CSharpUniqueNamer(t => t.Name); + var namer = new CSharpUniqueNamer(t => t.Name, new CSharpUtilities()); var table1 = new TableModel { Name = "A B C" }; var table2 = new TableModel { Name = "A_B_C" }; Assert.Equal("A_B_C", namer.GetName(table1)); diff --git a/test/EFCore.Design.Tests/Scaffolding/Internal/RelationalScaffoldingModelFactoryTest.cs b/test/EFCore.Design.Tests/Scaffolding/Internal/RelationalScaffoldingModelFactoryTest.cs index 95d99f388b6..8c62abbbbd3 100644 --- a/test/EFCore.Design.Tests/Scaffolding/Internal/RelationalScaffoldingModelFactoryTest.cs +++ b/test/EFCore.Design.Tests/Scaffolding/Internal/RelationalScaffoldingModelFactoryTest.cs @@ -1008,7 +1008,8 @@ public FakeScaffoldingModelFactory( new FakeDatabaseModelFactory(), new CandidateNamingService(), pluralizer, - new FakeScaffoldingHelper()) + new FakeScaffoldingHelper(), + new CSharpUtilities()) { } } @@ -1027,7 +1028,9 @@ public TypeScaffoldingInfo GetTypeScaffoldingInfo(ColumnModel columnModel) return null; } - var scaffoldingTypeMapper = new ScaffoldingTypeMapper(new TestTypeMapper(new RelationalTypeMapperDependencies())); + + var scaffoldingTypeMapper = new ScaffoldingTypeMapper( + new ScaffoldingTypeMapperDependencies(new TestTypeMapper(new RelationalTypeMapperDependencies()))); return scaffoldingTypeMapper.FindMapping(columnModel.StoreType, keyOrIndex: false, rowVersion: false); } diff --git a/test/EFCore.Design.Tests/Scaffolding/Internal/ReverseEngineeringConfigurationTests.cs b/test/EFCore.Design.Tests/Scaffolding/Internal/ReverseEngineeringConfigurationTests.cs index e167112f70f..946a3ac33c4 100644 --- a/test/EFCore.Design.Tests/Scaffolding/Internal/ReverseEngineeringConfigurationTests.cs +++ b/test/EFCore.Design.Tests/Scaffolding/Internal/ReverseEngineeringConfigurationTests.cs @@ -25,13 +25,14 @@ public void Throws_exceptions_for_invalid_context_name() private void ValidateContextNameInReverseEngineerGenerator(string contextName) { + var cSharpUtilities = new CSharpUtilities(); var reverseEngineer = new ModelScaffolder( new FakeScaffoldingModelFactory(new FakeDiagnosticsLogger()), new CSharpScaffoldingGenerator( new InMemoryFileService(), - new CSharpDbContextGenerator(new FakeScaffoldingHelper(), new FakeAnnotationRenderer(), CSharpUtilities.Instance), - new CSharpEntityTypeGenerator(CSharpUtilities.Instance)), - CSharpUtilities.Instance); + new CSharpDbContextGenerator(new FakeScaffoldingHelper(), new FakeAnnotationRenderer(), cSharpUtilities), + new CSharpEntityTypeGenerator(cSharpUtilities)), + cSharpUtilities); Assert.Equal( DesignStrings.ContextClassNotValidCSharpIdentifier(contextName), diff --git a/test/EFCore.SqlServer.Tests/Scaffolding/ScaffoldingTypeMapperSqlServerTest.cs b/test/EFCore.SqlServer.Tests/Scaffolding/ScaffoldingTypeMapperSqlServerTest.cs index 7b95d3d37dd..aaaa230a909 100644 --- a/test/EFCore.SqlServer.Tests/Scaffolding/ScaffoldingTypeMapperSqlServerTest.cs +++ b/test/EFCore.SqlServer.Tests/Scaffolding/ScaffoldingTypeMapperSqlServerTest.cs @@ -294,6 +294,7 @@ private static void AssertMapping(TypeScaffoldingInfo mapping, bool inferred, } private static ScaffoldingTypeMapper CreateMapper() - => new ScaffoldingTypeMapper(new SqlServerTypeMapper(new RelationalTypeMapperDependencies())); + => new ScaffoldingTypeMapper( + new ScaffoldingTypeMapperDependencies(new SqlServerTypeMapper(new RelationalTypeMapperDependencies()))); } } diff --git a/test/EFCore.Sqlite.Tests/Scaffolding/ScaffoldingTypeMapperSqliteTest.cs b/test/EFCore.Sqlite.Tests/Scaffolding/ScaffoldingTypeMapperSqliteTest.cs index 31083e237f4..7dc75e40102 100644 --- a/test/EFCore.Sqlite.Tests/Scaffolding/ScaffoldingTypeMapperSqliteTest.cs +++ b/test/EFCore.Sqlite.Tests/Scaffolding/ScaffoldingTypeMapperSqliteTest.cs @@ -129,6 +129,7 @@ private static void AssertMapping(TypeScaffoldingInfo mapping, bool inferred, } private static ScaffoldingTypeMapper CreateMapper() - => new ScaffoldingTypeMapper(new SqliteTypeMapper(new RelationalTypeMapperDependencies())); + => new ScaffoldingTypeMapper( + new ScaffoldingTypeMapperDependencies(new SqliteTypeMapper(new RelationalTypeMapperDependencies()))); } }