-
Couldn't load subscription status.
- Fork 5.2k
Fix binding types with optional string parameters #93563
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
ericstj
merged 9 commits into
dotnet:main
from
ericstj:config-binder-default-string-param
Nov 6, 2023
Merged
Changes from all commits
Commits
Show all changes
9 commits
Select commit
Hold shift + click to select a range
9d965aa
Add a baseline test for constructor parameters
ericstj 454a1cd
Fix binding types with optional string parameters
ericstj 776a195
Add a test case that uses a Primary Constructor with default values
ericstj 5be75ff
Merge remote-tracking branch 'upstream/main' into config-binder-defau…
ericstj 031453d
Split baseline data for added test.
ericstj 2582ecd
Merge branch 'main' of https://github.com/dotnet/runtime into config-…
ericstj 2dbb659
Fix .NETFramework test baseline
ericstj cecd367
Merge branch 'main' of https://github.com/dotnet/runtime into config-…
ericstj 1785832
Update baselines after global namespace change
ericstj File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
249 changes: 249 additions & 0 deletions
249
...r/tests/SourceGenerationTests/Baselines/net462/DefaultConstructorParameters.generated.txt
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,249 @@ | ||
| // <auto-generated/> | ||
|
|
||
| #nullable enable annotations | ||
| #nullable disable warnings | ||
|
|
||
| // Suppress warnings about [Obsolete] member usage in generated code. | ||
| #pragma warning disable CS0612, CS0618 | ||
|
|
||
| namespace System.Runtime.CompilerServices | ||
| { | ||
| using System; | ||
| using System.CodeDom.Compiler; | ||
|
|
||
| [GeneratedCode("Microsoft.Extensions.Configuration.Binder.SourceGeneration", "42.42.42.42")] | ||
| [AttributeUsage(AttributeTargets.Method, AllowMultiple = true)] | ||
| file sealed class InterceptsLocationAttribute : Attribute | ||
| { | ||
| public InterceptsLocationAttribute(string filePath, int line, int column) | ||
| { | ||
| } | ||
| } | ||
| } | ||
|
|
||
| namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration | ||
| { | ||
| using Microsoft.Extensions.Configuration; | ||
| using System; | ||
| using System.CodeDom.Compiler; | ||
| using System.Collections.Generic; | ||
| using System.Globalization; | ||
| using System.Runtime.CompilerServices; | ||
|
|
||
| [GeneratedCode("Microsoft.Extensions.Configuration.Binder.SourceGeneration", "42.42.42.42")] | ||
| file static class BindingExtensions | ||
| { | ||
| #region IConfiguration extensions. | ||
| /// <summary>Attempts to bind the given object instance to configuration values by matching property names against configuration keys recursively.</summary> | ||
| [InterceptsLocation(@"src-0.cs", 13, 16)] | ||
| public static void Bind_ProgramClassWhereParametersHaveDefaultValue(this IConfiguration configuration, object? instance) | ||
| { | ||
| if (configuration is null) | ||
| { | ||
| throw new ArgumentNullException(nameof(configuration)); | ||
| } | ||
|
|
||
| if (instance is null) | ||
| { | ||
| return; | ||
| } | ||
|
|
||
| var typedObj = (global::Program.ClassWhereParametersHaveDefaultValue)instance; | ||
| BindCore(configuration, ref typedObj, defaultValueIfNotFound: false, binderOptions: null); | ||
| } | ||
| #endregion IConfiguration extensions. | ||
|
|
||
| #region Core binding extensions. | ||
| private readonly static Lazy<HashSet<string>> s_configKeys_ProgramClassWhereParametersHaveDefaultValue = new(() => new HashSet<string>(StringComparer.OrdinalIgnoreCase) { "Name", "Address", "Age", "F", "D", "M", "SC", "C", "NAge", "NF", "ND", "NM", "NSC", "NC" }); | ||
|
|
||
| public static void BindCore(IConfiguration configuration, ref global::Program.ClassWhereParametersHaveDefaultValue instance, bool defaultValueIfNotFound, BinderOptions? binderOptions) | ||
| { | ||
| ValidateConfigurationKeys(typeof(global::Program.ClassWhereParametersHaveDefaultValue), s_configKeys_ProgramClassWhereParametersHaveDefaultValue, configuration, binderOptions); | ||
| } | ||
|
|
||
| public static global::Program.ClassWhereParametersHaveDefaultValue InitializeProgramClassWhereParametersHaveDefaultValue(IConfiguration configuration, BinderOptions? binderOptions) | ||
| { | ||
| string name = "John Doe"!; | ||
| if (configuration["Name"] is string value0) | ||
| { | ||
| name = value0; | ||
| } | ||
|
|
||
| string address = "1 Microsoft Way"!; | ||
| if (configuration["Address"] is string value1) | ||
| { | ||
| address = value1; | ||
| } | ||
|
|
||
| int age = (int)(42); | ||
| if (configuration["Age"] is string value2) | ||
| { | ||
| age = ParseInt(value2, () => configuration.GetSection("Age").Path); | ||
| } | ||
|
|
||
| float f = 42F; | ||
| if (configuration["F"] is string value3) | ||
| { | ||
| f = ParseFloat(value3, () => configuration.GetSection("F").Path); | ||
| } | ||
|
|
||
| double d = 3.1415899999999999D; | ||
| if (configuration["D"] is string value4) | ||
| { | ||
| d = ParseDouble(value4, () => configuration.GetSection("D").Path); | ||
| } | ||
|
|
||
| decimal m = 3.1415926535897932384626433M; | ||
| if (configuration["M"] is string value5) | ||
| { | ||
| m = ParseDecimal(value5, () => configuration.GetSection("M").Path); | ||
| } | ||
|
|
||
| global::System.StringComparison sc = (global::System.StringComparison)(4); | ||
| if (configuration["SC"] is string value6) | ||
| { | ||
| sc = ParseEnum<global::System.StringComparison>(value6, () => configuration.GetSection("SC").Path); | ||
| } | ||
|
|
||
| char c = 'q'; | ||
| if (configuration["C"] is string value7) | ||
| { | ||
| c = ParseChar(value7, () => configuration.GetSection("C").Path); | ||
| } | ||
|
|
||
| int? nage = (int?)(42); | ||
| if (configuration["NAge"] is string value8) | ||
| { | ||
| nage = ParseInt(value8, () => configuration.GetSection("NAge").Path); | ||
| } | ||
|
|
||
| float? nf = 42F; | ||
| if (configuration["NF"] is string value9) | ||
| { | ||
| nf = ParseFloat(value9, () => configuration.GetSection("NF").Path); | ||
| } | ||
|
|
||
| double? nd = 3.1415899999999999D; | ||
| if (configuration["ND"] is string value10) | ||
| { | ||
| nd = ParseDouble(value10, () => configuration.GetSection("ND").Path); | ||
| } | ||
|
|
||
| decimal? nm = 3.1415926535897932384626433M; | ||
| if (configuration["NM"] is string value11) | ||
| { | ||
| nm = ParseDecimal(value11, () => configuration.GetSection("NM").Path); | ||
| } | ||
|
|
||
| global::System.StringComparison? nsc = (global::System.StringComparison?)(4); | ||
| if (configuration["NSC"] is string value12) | ||
| { | ||
| nsc = ParseEnum<global::System.StringComparison>(value12, () => configuration.GetSection("NSC").Path); | ||
| } | ||
|
|
||
| char? nc = 'q'; | ||
| if (configuration["NC"] is string value13) | ||
| { | ||
| nc = ParseChar(value13, () => configuration.GetSection("NC").Path); | ||
| } | ||
|
|
||
| return new global::Program.ClassWhereParametersHaveDefaultValue(name, address, age, f, d, m, sc, c, nage, nf, nd, nm, nsc, nc); | ||
| } | ||
|
|
||
|
|
||
| /// <summary>If required by the binder options, validates that there are no unknown keys in the input configuration object.</summary> | ||
| public static void ValidateConfigurationKeys(Type type, Lazy<HashSet<string>> keys, IConfiguration configuration, BinderOptions? binderOptions) | ||
| { | ||
| if (binderOptions?.ErrorOnUnknownConfiguration is true) | ||
| { | ||
| List<string>? temp = null; | ||
|
|
||
| foreach (IConfigurationSection section in configuration.GetChildren()) | ||
| { | ||
| if (!keys.Value.Contains(section.Key)) | ||
| { | ||
| (temp ??= new List<string>()).Add($"'{section.Key}'"); | ||
| } | ||
| } | ||
|
|
||
| if (temp is not null) | ||
| { | ||
| throw new InvalidOperationException($"'ErrorOnUnknownConfiguration' was set on the provided BinderOptions, but the following properties were not found on the instance of {type}: {string.Join(", ", temp)}"); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| public static T ParseEnum<T>(string value, Func<string?> getPath) where T : struct | ||
| { | ||
| try | ||
| { | ||
| return (T)Enum.Parse(typeof(T), value, ignoreCase: true); | ||
| } | ||
| catch (Exception exception) | ||
| { | ||
| throw new InvalidOperationException($"Failed to convert configuration value at '{getPath()}' to type '{typeof(T)}'.", exception); | ||
| } | ||
| } | ||
|
|
||
| public static int ParseInt(string value, Func<string?> getPath) | ||
| { | ||
| try | ||
| { | ||
| return int.Parse(value, NumberStyles.Integer, CultureInfo.InvariantCulture); | ||
| } | ||
| catch (Exception exception) | ||
| { | ||
| throw new InvalidOperationException($"Failed to convert configuration value at '{getPath()}' to type '{typeof(int)}'.", exception); | ||
| } | ||
| } | ||
|
|
||
| public static float ParseFloat(string value, Func<string?> getPath) | ||
| { | ||
| try | ||
| { | ||
| return float.Parse(value, NumberStyles.Float, CultureInfo.InvariantCulture); | ||
| } | ||
| catch (Exception exception) | ||
| { | ||
| throw new InvalidOperationException($"Failed to convert configuration value at '{getPath()}' to type '{typeof(float)}'.", exception); | ||
| } | ||
| } | ||
|
|
||
| public static double ParseDouble(string value, Func<string?> getPath) | ||
| { | ||
| try | ||
| { | ||
| return double.Parse(value, NumberStyles.Float, CultureInfo.InvariantCulture); | ||
| } | ||
| catch (Exception exception) | ||
| { | ||
| throw new InvalidOperationException($"Failed to convert configuration value at '{getPath()}' to type '{typeof(double)}'.", exception); | ||
| } | ||
| } | ||
|
|
||
| public static decimal ParseDecimal(string value, Func<string?> getPath) | ||
| { | ||
| try | ||
| { | ||
| return decimal.Parse(value, NumberStyles.Float, CultureInfo.InvariantCulture); | ||
| } | ||
| catch (Exception exception) | ||
| { | ||
| throw new InvalidOperationException($"Failed to convert configuration value at '{getPath()}' to type '{typeof(decimal)}'.", exception); | ||
| } | ||
| } | ||
|
|
||
| public static char ParseChar(string value, Func<string?> getPath) | ||
| { | ||
| try | ||
| { | ||
| return char.Parse(value); | ||
| } | ||
| catch (Exception exception) | ||
| { | ||
| throw new InvalidOperationException($"Failed to convert configuration value at '{getPath()}' to type '{typeof(char)}'.", exception); | ||
| } | ||
| } | ||
| #endregion Core binding extensions. | ||
| } | ||
| } |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.