diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Emitter/ConfigurationBinder.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Emitter/ConfigurationBinder.cs index c4f128cffd6c1..f1c7d5f7ff215 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Emitter/ConfigurationBinder.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Emitter/ConfigurationBinder.cs @@ -148,7 +148,7 @@ void EmitMethods(MethodsToGen_ConfigurationBinder method, string additionalParam EmitCheckForNullArgument_WithBlankLine(Identifier.instance, voidReturn: true); _writer.WriteLine($$""" var {{Identifier.typedObj}} = ({{type.EffectiveType.DisplayString}}){{Identifier.instance}}; - {{nameof(MethodsToGen_CoreBindingHelper.BindCore)}}({{configExpression}}, ref {{Identifier.typedObj}}, {{binderOptionsArg}}); + {{nameof(MethodsToGen_CoreBindingHelper.BindCore)}}({{configExpression}}, ref {{Identifier.typedObj}}, defaultValueIfNotFound: false, {{binderOptionsArg}}); """); } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Emitter/CoreBindingHelpers.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Emitter/CoreBindingHelpers.cs index 7b698544c9151..90531efe1b0c1 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Emitter/CoreBindingHelpers.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Emitter/CoreBindingHelpers.cs @@ -97,6 +97,7 @@ private void EmitGetCoreMethod() Expression.sectionPath, writeOnSuccess: parsedValueExpr => _writer.WriteLine($"return {parsedValueExpr};"), checkForNullSectionValue: stringParsableType.StringParsableTypeKind is not StringParsableTypeKind.AssignFromSectionValue, + useDefaultValueIfSectionValueIsNull: false, useIncrementalStringValueIdentifier: false); } break; @@ -110,7 +111,7 @@ private void EmitGetCoreMethod() { if (complexType.CanInstantiate) { - EmitBindingLogic(complexType, Identifier.instance, Identifier.configuration, InitializationKind.Declaration); + EmitBindingLogic(complexType, Identifier.instance, Identifier.configuration, InitializationKind.Declaration, ValueDefaulting.CallSetter); _writer.WriteLine($"return {Identifier.instance};"); } else if (type is ObjectSpec { InitExceptionMessage: string exMsg }) @@ -173,6 +174,7 @@ private void EmitGetValueCoreMethod() Expression.sectionPath, writeOnSuccess: (parsedValueExpr) => _writer.WriteLine($"return {parsedValueExpr};"), checkForNullSectionValue: false, + useDefaultValueIfSectionValueIsNull: false, useIncrementalStringValueIdentifier: false); EmitEndBlock(); @@ -207,7 +209,7 @@ private void EmitBindCoreMainMethod() EmitStartBlock($"{conditionKindExpr} ({Identifier.type} == typeof({type.DisplayString}))"); _writer.WriteLine($"var {Identifier.temp} = ({effectiveType.DisplayString}){Identifier.instance};"); - EmitBindingLogic(type, Identifier.temp, Identifier.configuration, InitializationKind.None); + EmitBindingLogic(type, Identifier.temp, Identifier.configuration, InitializationKind.None, ValueDefaulting.None); _writer.WriteLine($"return;"); EmitEndBlock(); } @@ -235,7 +237,7 @@ private void EmitBindCoreMethods() private void EmitBindCoreMethod(ComplexTypeSpec type) { string objParameterExpression = $"ref {type.DisplayString} {Identifier.instance}"; - EmitStartBlock(@$"public static void {nameof(MethodsToGen_CoreBindingHelper.BindCore)}({Identifier.IConfiguration} {Identifier.configuration}, {objParameterExpression}, {Identifier.BinderOptions}? {Identifier.binderOptions})"); + EmitStartBlock(@$"public static void {nameof(MethodsToGen_CoreBindingHelper.BindCore)}({Identifier.IConfiguration} {Identifier.configuration}, {objParameterExpression}, bool defaultValueIfNotFound, {Identifier.BinderOptions}? {Identifier.binderOptions})"); ComplexTypeSpec effectiveType = (ComplexTypeSpec)type.EffectiveType; if (effectiveType is EnumerableSpec enumerable) @@ -334,8 +336,6 @@ private void EmitInitializeMethod(ObjectSpec type) void EmitBindImplForMember(MemberSpec member) { TypeSpec memberType = member.Type; - bool errorOnFailedBinding = member.ErrorOnFailedBinding; - string parsedMemberDeclarationLhs = $"{memberType.DisplayString} {member.Name}"; string configKeyName = member.ConfigurationKeyName; string parsedMemberAssignmentLhsExpr; @@ -344,7 +344,7 @@ void EmitBindImplForMember(MemberSpec member) { case ParsableFromStringSpec { StringParsableTypeKind: StringParsableTypeKind.AssignFromSectionValue }: { - if (errorOnFailedBinding) + if (member is ParameterSpec parameter && parameter.ErrorOnFailedBinding) { string condition = $@"if ({Identifier.configuration}[""{configKeyName}""] is not {parsedMemberDeclarationLhs})"; EmitThrowBlock(condition); @@ -377,11 +377,12 @@ void EmitBindImplForMember(MemberSpec member) member, parsedMemberAssignmentLhsExpr, sectionPathExpr: GetSectionPathFromConfigurationExpression(configKeyName), - canSet: true); + canSet: true, + InitializationKind.None); if (canBindToMember) { - if (errorOnFailedBinding) + if (member is ParameterSpec parameter && parameter.ErrorOnFailedBinding) { // Add exception logic for parameter ctors; must be present in configuration object. EmitThrowBlock(condition: "else"); @@ -633,7 +634,7 @@ private void EmitPopulationImplForArray(EnumerableSpec type) // Create list and bind elements. string tempIdentifier = GetIncrementalIdentifier(Identifier.temp); - EmitBindingLogic(typeToInstantiate, tempIdentifier, Identifier.configuration, InitializationKind.Declaration); + EmitBindingLogic(typeToInstantiate, tempIdentifier, Identifier.configuration, InitializationKind.Declaration, ValueDefaulting.None); // Resize array and add binded elements. _writer.WriteLine($$""" @@ -661,6 +662,7 @@ private void EmitPopulationImplForEnumerableWithAdd(EnumerableSpec type) Expression.sectionPath, (parsedValueExpr) => _writer.WriteLine($"{addExpr}({parsedValueExpr});"), checkForNullSectionValue: true, + useDefaultValueIfSectionValueIsNull: false, useIncrementalStringValueIdentifier: false); } break; @@ -671,7 +673,7 @@ private void EmitPopulationImplForEnumerableWithAdd(EnumerableSpec type) break; case ComplexTypeSpec { CanInstantiate: true } complexType: { - EmitBindingLogic(complexType, Identifier.value, Identifier.section, InitializationKind.Declaration); + EmitBindingLogic(complexType, Identifier.value, Identifier.section, InitializationKind.Declaration, ValueDefaulting.None); _writer.WriteLine($"{addExpr}({Identifier.value});"); } break; @@ -696,6 +698,7 @@ private void EmitBindCoreImplForDictionary(DictionarySpec type) Expression.sectionPath, Emit_BindAndAddLogic_ForElement, checkForNullSectionValue: false, + useDefaultValueIfSectionValueIsNull: false, useIncrementalStringValueIdentifier: false); void Emit_BindAndAddLogic_ForElement(string parsedKeyExpr) @@ -710,6 +713,7 @@ void Emit_BindAndAddLogic_ForElement(string parsedKeyExpr) Expression.sectionPath, writeOnSuccess: parsedValueExpr => _writer.WriteLine($"{instanceIdentifier}[{parsedKeyExpr}] = {parsedValueExpr};"), checkForNullSectionValue: true, + useDefaultValueIfSectionValueIsNull: false, useIncrementalStringValueIdentifier: false); } break; @@ -746,7 +750,7 @@ void Emit_BindAndAddLogic_ForElement(string parsedKeyExpr) EmitObjectInit(complexElementType, Identifier.element, InitializationKind.SimpleAssignment, Identifier.section); EmitEndBlock(); - EmitBindingLogic(complexElementType, Identifier.element, Identifier.section, InitializationKind.None); + EmitBindingLogic(complexElementType, Identifier.element, Identifier.section, InitializationKind.None, ValueDefaulting.None); _writer.WriteLine($"{instanceIdentifier}[{parsedKeyExpr}] = {Identifier.element};"); } break; @@ -774,7 +778,8 @@ private void EmitBindCoreImplForObject(ObjectSpec type) property, memberAccessExpr: $"{containingTypeRef}.{property.Name}", GetSectionPathFromConfigurationExpression(property.ConfigurationKeyName), - canSet: property.CanSet); + canSet: property.CanSet, + InitializationKind.Declaration); } } } @@ -783,9 +788,11 @@ private bool EmitBindImplForMember( MemberSpec member, string memberAccessExpr, string sectionPathExpr, - bool canSet) + bool canSet, + InitializationKind initializationKind) { TypeSpec effectiveMemberType = member.Type.EffectiveType; + string sectionParseExpr = GetSectionFromConfigurationExpression(member.ConfigurationKeyName); switch (effectiveMemberType) @@ -794,19 +801,20 @@ private bool EmitBindImplForMember( { if (canSet) { - bool checkForNullSectionValue = member is ParameterSpec - ? true - : stringParsableType.StringParsableTypeKind is not StringParsableTypeKind.AssignFromSectionValue; - - string nullBangExpr = checkForNullSectionValue ? string.Empty : "!"; + bool useDefaultValueIfSectionValueIsNull = + initializationKind == InitializationKind.Declaration && + member is PropertySpec && + member.Type.IsValueType && + member.Type.SpecKind is not TypeSpecKind.Nullable; EmitBlankLineIfRequired(); EmitBindingLogic( stringParsableType, $@"{Identifier.configuration}[""{member.ConfigurationKeyName}""]", sectionPathExpr, - writeOnSuccess: parsedValueExpr => _writer.WriteLine($"{memberAccessExpr} = {parsedValueExpr}{nullBangExpr};"), - checkForNullSectionValue, + writeOnSuccess: parsedValueExpr => _writer.WriteLine($"{memberAccessExpr} = {parsedValueExpr};"), + checkForNullSectionValue: true, + useDefaultValueIfSectionValueIsNull, useIncrementalStringValueIdentifier: true); } @@ -906,7 +914,9 @@ private void EmitBindingLogicForComplexMember( targetObjAccessExpr, configArgExpr, initKind, - writeOnSuccess); + ValueDefaulting.None, + writeOnSuccess + ); } private void EmitBindingLogic( @@ -914,6 +924,7 @@ private void EmitBindingLogic( string memberAccessExpr, string configArgExpr, InitializationKind initKind, + ValueDefaulting valueDefaulting, Action? writeOnSuccess = null) { if (!type.HasBindableMembers) @@ -952,7 +963,7 @@ private void EmitBindingLogic( void EmitBindingLogic(string instanceToBindExpr, InitializationKind initKind) { - string bindCoreCall = $@"{nameof(MethodsToGen_CoreBindingHelper.BindCore)}({configArgExpr}, ref {instanceToBindExpr}, {Identifier.binderOptions});"; + string bindCoreCall = $@"{nameof(MethodsToGen_CoreBindingHelper.BindCore)}({configArgExpr}, ref {instanceToBindExpr}, defaultValueIfNotFound: {FormatDefaultValueIfNotFound()}, {Identifier.binderOptions});"; if (type.CanInstantiate) { @@ -984,6 +995,8 @@ void EmitBindCoreCall() _writer.WriteLine(bindCoreCall); writeOnSuccess?.Invoke(instanceToBindExpr); } + + string FormatDefaultValueIfNotFound() => valueDefaulting == ValueDefaulting.CallSetter ? "true" : "false"; } } @@ -993,6 +1006,7 @@ private void EmitBindingLogic( string sectionPathExpr, Action? writeOnSuccess, bool checkForNullSectionValue, + bool useDefaultValueIfSectionValueIsNull, bool useIncrementalStringValueIdentifier) { StringParsableTypeKind typeKind = type.StringParsableTypeKind; @@ -1018,6 +1032,14 @@ private void EmitBindingLogic( EmitEndBlock(); } + if (useDefaultValueIfSectionValueIsNull) + { + parsedValueExpr = $"default"; + EmitStartBlock($"else if (defaultValueIfNotFound)"); + InvokeWriteOnSuccess(); + EmitEndBlock(); + } + void InvokeWriteOnSuccess() => writeOnSuccess?.Invoke(parsedValueExpr); } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Emitter/Helpers.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Emitter/Helpers.cs index 8bac0f4f5af03..a7db2fb516397 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Emitter/Helpers.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Emitter/Helpers.cs @@ -24,6 +24,23 @@ private enum InitializationKind Declaration = 3, } + /// + /// The type of defaulting for a property if it does not have a config entry. + /// This should only be applied for "Get" cases, not "Bind" and is also conditioned + /// on the source generated for a particular property as to whether it uses this value. + /// Note this is different than "InitializationKind.Declaration" since it only applied to + /// complex types and not arrays\enumerables. + /// + private enum ValueDefaulting + { + None = 0, + + /// + /// Call the setter with the default value for the property's Type. + /// + CallSetter = 1, + } + private static class Expression { public const string configurationGetSection = "configuration.GetSection"; diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Specs/Members/MemberSpec.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Specs/Members/MemberSpec.cs index 4bf674f597502..effd550482595 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Specs/Members/MemberSpec.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Specs/Members/MemberSpec.cs @@ -16,7 +16,6 @@ public MemberSpec(ISymbol member) } public string Name { get; } - public bool ErrorOnFailedBinding { get; protected set; } public string DefaultValueExpr { get; protected set; } public required TypeSpec Type { get; init; } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Specs/Members/ParameterSpec.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Specs/Members/ParameterSpec.cs index 9b5e4360c1116..0f17a6247f74d 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Specs/Members/ParameterSpec.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Specs/Members/ParameterSpec.cs @@ -26,6 +26,8 @@ public ParameterSpec(IParameterSymbol parameter) : base(parameter) } } + public bool ErrorOnFailedBinding { get; private set; } + public RefKind RefKind { get; } public override bool CanGet => false; diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Specs/Types/SimpleTypeSpec.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Specs/Types/SimpleTypeSpec.cs index 50e488008ad68..2dfe08dc5f547 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Specs/Types/SimpleTypeSpec.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Specs/Types/SimpleTypeSpec.cs @@ -54,7 +54,7 @@ internal enum StringParsableTypeKind None = 0, /// - /// Declared types that can be assigned directly from IConfigurationSection.Value, i.e. string and tyepof(object). + /// Declared types that can be assigned directly from IConfigurationSection.Value, i.e. string and typeof(object). /// AssignFromSectionValue = 1, Enum = 2, diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/Common/ConfigurationBinderTests.TestClasses.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/Common/ConfigurationBinderTests.TestClasses.cs index e92ed06180874..f47cdbe6dbbb5 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/Common/ConfigurationBinderTests.TestClasses.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/Common/ConfigurationBinderTests.TestClasses.cs @@ -443,6 +443,10 @@ public record NestedConfig(string MyProp); public class OptionWithCollectionProperties { private int _otherCode; + private int _otherCodeNullable; + private string _otherCodeString = "default"; + private object _otherCodeNull; + private Uri _otherCodeUri; private ICollection blacklist = new HashSet(); public ICollection Blacklist @@ -460,12 +464,37 @@ public ICollection Blacklist // ParsedBlacklist initialized using the setter of Blacklist. public ICollection ParsedBlacklist { get; private set; } = new HashSet(); - // This property not having any match in the configuration. Still the setter need to be called during the binding. + // This does not have a match in the configuration, however the setter should be called during the binding: public int OtherCode { get => _otherCode; set => _otherCode = value == 0 ? 2 : value; } + + // These do not have any match in the configuration, and the setters should not be called during the binding: + public int? OtherCodeNullable + { + get => _otherCodeNullable; + set => _otherCodeNullable = !value.HasValue ? 3 : value.Value; + } + + public string OtherCodeString + { + get => _otherCodeString; + set => _otherCodeString = value; + } + + public object? OtherCodeNull + { + get => _otherCodeNull; + set => _otherCodeNull = value is null ? 4 : value; + } + + public Uri OtherCodeUri + { + get => _otherCodeUri; + set => _otherCodeUri = value is null ? new Uri("hello") : value; + } } public interface ISomeInterface @@ -545,6 +574,47 @@ public struct DeeplyNested } } + public struct StructWithNestedStructAndSetterLogic + { + private string _string; + private int _int32; + + public string String + { + get => _string; + // Setter should not be called for missing values. + set { _string = string.IsNullOrEmpty(value) ? "Hello" : value; } + } + + public int Int32 + { + get => _int32; + set { _int32 = value == 0 ? 42 : value; } + } + + public Nested NestedStruct; + public Nested[] NestedStructs; + + public struct Nested + { + private string _string; + private int _int32; + + public string String + { + get => _string; + // Setter should not be called for missing values. + set { _string = string.IsNullOrEmpty(value) ? "Hello2" : value; } + } + + public int Int32 + { + get => _int32; + set { _int32 = value == 0 ? 43 : value; } + } + } + } + public class BaseClassWithVirtualProperty { private string? PrivateProperty { get; set; } @@ -796,5 +866,27 @@ internal class ClassWith_DirectlyAssignable_CtorParams public ClassWith_DirectlyAssignable_CtorParams(IConfigurationSection mySection, object myObject, string myString) => (MySection, MyObject, MyString) = (mySection, myObject, myString); } + + public class SharedChildInstance_Class + { + public string? ConnectionString { get; set; } + } + + public class ClassThatThrowsOnSetters + { + private int _myIntProperty; + + public ClassThatThrowsOnSetters() + { + _myIntProperty = 42; + } + + public int MyIntProperty + { + get => _myIntProperty; + set => throw new InvalidOperationException("Not expected"); + } + } + } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/Common/ConfigurationBinderTests.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/Common/ConfigurationBinderTests.cs index 2a6006b38a271..7c955e789184c 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/Common/ConfigurationBinderTests.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/Common/ConfigurationBinderTests.cs @@ -1580,6 +1580,53 @@ public void CanBindNestedStructProperties() Assert.True(bound.ReadWriteNestedStruct.DeeplyNested.Boolean); } + [Fact] + public void CanBindNestedStructProperties_SetterCalledWithMissingConfigEntry() + { + ConfigurationBuilder configurationBuilder = new(); + configurationBuilder.AddInMemoryCollection(new Dictionary + { + { "dmy", "dmy" }, + }); + + IConfiguration config = configurationBuilder.Build(); + + var bound = config.Get(); + Assert.Null(bound.String); + Assert.Null(bound.NestedStruct.String); + Assert.Equal(42, bound.Int32); + Assert.Equal(0, bound.NestedStruct.Int32); + } + + [Fact] + public void CanBindNestedStructProperties_SetterNotCalledWithMissingConfigSection() + { + ConfigurationBuilder configurationBuilder = new(); + configurationBuilder.AddInMemoryCollection(new Dictionary + { + // An empty value will not trigger defaulting. + }); + + IConfiguration config = configurationBuilder.Build(); + + var bound = config.Get(); + Assert.Null(bound.String); + Assert.Null(bound.NestedStruct.String); + Assert.Equal(0, bound.Int32); + Assert.Equal(0, bound.NestedStruct.Int32); + } + + [Fact] + public void CanBindNestedStructProperties_SetterCalledWithMissingConfig_Array() + { + var config = TestHelpers.GetConfigurationFromJsonString( + """{"value": [{ }]}"""); + + var bound = config.GetSection("value").Get(); + Assert.Null(bound[0].String); + Assert.Equal(0, bound[0].Int32); + } + [Fact] public void IgnoresReadOnlyNestedStructProperties() { @@ -1712,13 +1759,29 @@ public void EnsureCallingThePropertySetter() Assert.Equal(2, options.ParsedBlacklist.Count); // should be initialized when calling the options.Blacklist setter. Assert.Equal(401, options.HttpStatusCode); // exists in configuration and properly sets the property -#if BUILDING_SOURCE_GENERATOR_TESTS - // Setter not called if there's no matching configuration value. - Assert.Equal(0, options.OtherCode); -#else - // doesn't exist in configuration. the setter sets default value '2' + + // This doesn't exist in configuration but the setter should be called which defaults the to '2' from input of '0'. Assert.Equal(2, options.OtherCode); -#endif + + // These don't exist in configuration and setters are not called since they are nullable. + Assert.Equal(0, options.OtherCodeNullable); + Assert.Equal("default", options.OtherCodeString); + Assert.Null(options.OtherCodeNull); + Assert.Null(options.OtherCodeUri); + } + + [Fact] + public void EnsureNotCallingSettersWhenGivenExistingInstanceNotInConfig() + { + var builder = new ConfigurationBuilder(); + builder.AddInMemoryCollection(new KeyValuePair[] { }); + var config = builder.Build(); + + ClassThatThrowsOnSetters instance = new(); + + // The setter for MyIntProperty throws, so this verifies that the setter is not called. + config.GetSection("Dmy").Bind(instance); + Assert.Equal(42, instance.MyIntProperty); } [Fact] @@ -2321,5 +2384,25 @@ public void IConfigurationSectionAsCtorParam() Assert.Equal("MyObject", obj.MyObject); Assert.Equal("MyString", obj.MyString); } + + [Fact] + public void SharedChildInstance() + { + var builder = new ConfigurationBuilder(); + builder.AddInMemoryCollection(new KeyValuePair[] + { + new("A:B:ConnectionString", "localhost"), + }); + + var config = builder.Build(); + + SharedChildInstance_Class instance = new(); + config.GetSection("A:B").Bind(instance); + Assert.Equal("localhost", instance.ConnectionString); + + // Binding to a new section should not set the value to null. + config.GetSection("A").Bind(instance); + Assert.Equal("localhost", instance.ConnectionString); + } } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/Collections.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/Collections.generated.txt index 775d9052ded43..ddd52c68b9989 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/Collections.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/Collections.generated.txt @@ -56,14 +56,14 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration if (type == typeof(Program.MyClassWithCustomCollections)) { var instance = new Program.MyClassWithCustomCollections(); - BindCore(configuration, ref instance, binderOptions); + BindCore(configuration, ref instance, defaultValueIfNotFound: true, binderOptions); return instance; } throw new NotSupportedException($"Unable to bind to type '{type}': generator did not detect the type as input."); } - public static void BindCore(IConfiguration configuration, ref Program.CustomDictionary instance, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref Program.CustomDictionary instance, bool defaultValueIfNotFound, BinderOptions? binderOptions) { foreach (IConfigurationSection section in configuration.GetChildren()) { @@ -74,7 +74,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration } } - public static void BindCore(IConfiguration configuration, ref Program.CustomList instance, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref Program.CustomList instance, bool defaultValueIfNotFound, BinderOptions? binderOptions) { foreach (IConfigurationSection section in configuration.GetChildren()) { @@ -85,7 +85,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration } } - public static void BindCore(IConfiguration configuration, ref List instance, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref List instance, bool defaultValueIfNotFound, BinderOptions? binderOptions) { foreach (IConfigurationSection section in configuration.GetChildren()) { @@ -96,7 +96,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration } } - public static void BindCore(IConfiguration configuration, ref ICollection instance, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref ICollection instance, bool defaultValueIfNotFound, BinderOptions? binderOptions) { foreach (IConfigurationSection section in configuration.GetChildren()) { @@ -107,7 +107,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration } } - public static void BindCore(IConfiguration configuration, ref IReadOnlyList instance, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref IReadOnlyList instance, bool defaultValueIfNotFound, BinderOptions? binderOptions) { if (instance is not ICollection temp) { @@ -123,7 +123,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration } } - public static void BindCore(IConfiguration configuration, ref Dictionary instance, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref Dictionary instance, bool defaultValueIfNotFound, BinderOptions? binderOptions) { foreach (IConfigurationSection section in configuration.GetChildren()) { @@ -134,7 +134,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration } } - public static void BindCore(IConfiguration configuration, ref IDictionary instance, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref IDictionary instance, bool defaultValueIfNotFound, BinderOptions? binderOptions) { foreach (IConfigurationSection section in configuration.GetChildren()) { @@ -145,7 +145,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration } } - public static void BindCore(IConfiguration configuration, ref IReadOnlyDictionary instance, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref IReadOnlyDictionary instance, bool defaultValueIfNotFound, BinderOptions? binderOptions) { if (instance is not IDictionary temp) { @@ -161,7 +161,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration } } - public static void BindCore(IConfiguration configuration, ref Program.MyClassWithCustomCollections instance, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref Program.MyClassWithCustomCollections instance, bool defaultValueIfNotFound, BinderOptions? binderOptions) { ValidateConfigurationKeys(typeof(Program.MyClassWithCustomCollections), s_configKeys_ProgramMyClassWithCustomCollections, configuration, binderOptions); @@ -169,7 +169,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { Program.CustomDictionary? temp3 = instance.CustomDictionary; temp3 ??= new Program.CustomDictionary(); - BindCore(section1, ref temp3, binderOptions); + BindCore(section1, ref temp3, defaultValueIfNotFound: false, binderOptions); instance.CustomDictionary = temp3; } @@ -177,7 +177,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { Program.CustomList? temp6 = instance.CustomList; temp6 ??= new Program.CustomList(); - BindCore(section4, ref temp6, binderOptions); + BindCore(section4, ref temp6, defaultValueIfNotFound: false, binderOptions); instance.CustomList = temp6; } @@ -185,7 +185,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { IReadOnlyList? temp9 = instance.IReadOnlyList; temp9 = temp9 is null ? new List() : new List(temp9); - BindCore(section7, ref temp9, binderOptions); + BindCore(section7, ref temp9, defaultValueIfNotFound: false, binderOptions); instance.IReadOnlyList = temp9; } @@ -193,7 +193,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { IReadOnlyDictionary? temp12 = instance.IReadOnlyDictionary; temp12 = temp12 is null ? new Dictionary() : temp12.ToDictionary(pair => pair.Key, pair => pair.Value); - BindCore(section10, ref temp12, binderOptions); + BindCore(section10, ref temp12, defaultValueIfNotFound: false, binderOptions); instance.IReadOnlyDictionary = temp12; } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Bind.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Bind.generated.txt index e5b37775cffd4..fc0dda4b5b3ae 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Bind.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Bind.generated.txt @@ -45,7 +45,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration } var typedObj = (Program.MyClass)instance; - BindCore(configuration, ref typedObj, binderOptions: null); + BindCore(configuration, ref typedObj, defaultValueIfNotFound: false, binderOptions: null); } /// Attempts to bind the given object instance to configuration values by matching property names against configuration keys recursively. @@ -63,7 +63,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration } var typedObj = (Program.MyClass)instance; - BindCore(configuration, ref typedObj, GetBinderOptions(configureOptions)); + BindCore(configuration, ref typedObj, defaultValueIfNotFound: false, GetBinderOptions(configureOptions)); } /// Attempts to bind the given object instance to configuration values by matching property names against configuration keys recursively. @@ -81,14 +81,14 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration } var typedObj = (Program.MyClass)instance; - BindCore(configuration.GetSection(key), ref typedObj, binderOptions: null); + BindCore(configuration.GetSection(key), ref typedObj, defaultValueIfNotFound: false, binderOptions: null); } #endregion IConfiguration extensions. #region Core binding extensions. private readonly static Lazy> s_configKeys_ProgramMyClass = new(() => new HashSet(StringComparer.OrdinalIgnoreCase) { "MyString", "MyInt", "MyList", "MyDictionary", "MyComplexDictionary" }); - public static void BindCore(IConfiguration configuration, ref List instance, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref List instance, bool defaultValueIfNotFound, BinderOptions? binderOptions) { foreach (IConfigurationSection section in configuration.GetChildren()) { @@ -99,7 +99,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration } } - public static void BindCore(IConfiguration configuration, ref Dictionary instance, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref Dictionary instance, bool defaultValueIfNotFound, BinderOptions? binderOptions) { foreach (IConfigurationSection section in configuration.GetChildren()) { @@ -110,7 +110,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration } } - public static void BindCore(IConfiguration configuration, ref Dictionary instance, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref Dictionary instance, bool defaultValueIfNotFound, BinderOptions? binderOptions) { foreach (IConfigurationSection section in configuration.GetChildren()) { @@ -122,22 +122,29 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration } } - public static void BindCore(IConfiguration configuration, ref Program.MyClass instance, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref Program.MyClass instance, bool defaultValueIfNotFound, BinderOptions? binderOptions) { ValidateConfigurationKeys(typeof(Program.MyClass), s_configKeys_ProgramMyClass, configuration, binderOptions); - instance.MyString = configuration["MyString"]!; + if (configuration["MyString"] is string value0) + { + instance.MyString = value0; + } if (configuration["MyInt"] is string value1) { instance.MyInt = ParseInt(value1, () => configuration.GetSection("MyInt").Path); } + else if (defaultValueIfNotFound) + { + instance.MyInt = default; + } if (AsConfigWithChildren(configuration.GetSection("MyList")) is IConfigurationSection section2) { List? temp4 = instance.MyList; temp4 ??= new List(); - BindCore(section2, ref temp4, binderOptions); + BindCore(section2, ref temp4, defaultValueIfNotFound: false, binderOptions); instance.MyList = temp4; } @@ -145,7 +152,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { Dictionary? temp7 = instance.MyDictionary; temp7 ??= new Dictionary(); - BindCore(section5, ref temp7, binderOptions); + BindCore(section5, ref temp7, defaultValueIfNotFound: false, binderOptions); instance.MyDictionary = temp7; } @@ -153,7 +160,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { Dictionary? temp10 = instance.MyComplexDictionary; temp10 ??= new Dictionary(); - BindCore(section8, ref temp10, binderOptions); + BindCore(section8, ref temp10, defaultValueIfNotFound: false, binderOptions); instance.MyComplexDictionary = temp10; } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Bind_Instance.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Bind_Instance.generated.txt index fc35d29e69334..9cbc0a22c5c84 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Bind_Instance.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Bind_Instance.generated.txt @@ -45,14 +45,14 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration } var typedObj = (Program.MyClass)instance; - BindCore(configuration, ref typedObj, binderOptions: null); + BindCore(configuration, ref typedObj, defaultValueIfNotFound: false, binderOptions: null); } #endregion IConfiguration extensions. #region Core binding extensions. private readonly static Lazy> s_configKeys_ProgramMyClass = new(() => new HashSet(StringComparer.OrdinalIgnoreCase) { "MyString", "MyInt", "MyList", "MyDictionary", "MyComplexDictionary" }); - public static void BindCore(IConfiguration configuration, ref List instance, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref List instance, bool defaultValueIfNotFound, BinderOptions? binderOptions) { foreach (IConfigurationSection section in configuration.GetChildren()) { @@ -63,7 +63,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration } } - public static void BindCore(IConfiguration configuration, ref Dictionary instance, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref Dictionary instance, bool defaultValueIfNotFound, BinderOptions? binderOptions) { foreach (IConfigurationSection section in configuration.GetChildren()) { @@ -74,7 +74,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration } } - public static void BindCore(IConfiguration configuration, ref Dictionary instance, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref Dictionary instance, bool defaultValueIfNotFound, BinderOptions? binderOptions) { foreach (IConfigurationSection section in configuration.GetChildren()) { @@ -86,22 +86,29 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration } } - public static void BindCore(IConfiguration configuration, ref Program.MyClass instance, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref Program.MyClass instance, bool defaultValueIfNotFound, BinderOptions? binderOptions) { ValidateConfigurationKeys(typeof(Program.MyClass), s_configKeys_ProgramMyClass, configuration, binderOptions); - instance.MyString = configuration["MyString"]!; + if (configuration["MyString"] is string value0) + { + instance.MyString = value0; + } if (configuration["MyInt"] is string value1) { instance.MyInt = ParseInt(value1, () => configuration.GetSection("MyInt").Path); } + else if (defaultValueIfNotFound) + { + instance.MyInt = default; + } if (AsConfigWithChildren(configuration.GetSection("MyList")) is IConfigurationSection section2) { List? temp4 = instance.MyList; temp4 ??= new List(); - BindCore(section2, ref temp4, binderOptions); + BindCore(section2, ref temp4, defaultValueIfNotFound: false, binderOptions); instance.MyList = temp4; } @@ -109,7 +116,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { Dictionary? temp7 = instance.MyDictionary; temp7 ??= new Dictionary(); - BindCore(section5, ref temp7, binderOptions); + BindCore(section5, ref temp7, defaultValueIfNotFound: false, binderOptions); instance.MyDictionary = temp7; } @@ -117,7 +124,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { Dictionary? temp10 = instance.MyComplexDictionary; temp10 ??= new Dictionary(); - BindCore(section8, ref temp10, binderOptions); + BindCore(section8, ref temp10, defaultValueIfNotFound: false, binderOptions); instance.MyComplexDictionary = temp10; } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Bind_Instance_BinderOptions.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Bind_Instance_BinderOptions.generated.txt index 0d3eb884c966e..f3efa07fc0c5c 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Bind_Instance_BinderOptions.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Bind_Instance_BinderOptions.generated.txt @@ -45,14 +45,14 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration } var typedObj = (Program.MyClass)instance; - BindCore(configuration, ref typedObj, GetBinderOptions(configureOptions)); + BindCore(configuration, ref typedObj, defaultValueIfNotFound: false, GetBinderOptions(configureOptions)); } #endregion IConfiguration extensions. #region Core binding extensions. private readonly static Lazy> s_configKeys_ProgramMyClass = new(() => new HashSet(StringComparer.OrdinalIgnoreCase) { "MyString", "MyInt", "MyList", "MyDictionary", "MyComplexDictionary" }); - public static void BindCore(IConfiguration configuration, ref List instance, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref List instance, bool defaultValueIfNotFound, BinderOptions? binderOptions) { foreach (IConfigurationSection section in configuration.GetChildren()) { @@ -63,7 +63,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration } } - public static void BindCore(IConfiguration configuration, ref Dictionary instance, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref Dictionary instance, bool defaultValueIfNotFound, BinderOptions? binderOptions) { foreach (IConfigurationSection section in configuration.GetChildren()) { @@ -74,7 +74,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration } } - public static void BindCore(IConfiguration configuration, ref Dictionary instance, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref Dictionary instance, bool defaultValueIfNotFound, BinderOptions? binderOptions) { foreach (IConfigurationSection section in configuration.GetChildren()) { @@ -86,22 +86,29 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration } } - public static void BindCore(IConfiguration configuration, ref Program.MyClass instance, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref Program.MyClass instance, bool defaultValueIfNotFound, BinderOptions? binderOptions) { ValidateConfigurationKeys(typeof(Program.MyClass), s_configKeys_ProgramMyClass, configuration, binderOptions); - instance.MyString = configuration["MyString"]!; + if (configuration["MyString"] is string value0) + { + instance.MyString = value0; + } if (configuration["MyInt"] is string value1) { instance.MyInt = ParseInt(value1, () => configuration.GetSection("MyInt").Path); } + else if (defaultValueIfNotFound) + { + instance.MyInt = default; + } if (AsConfigWithChildren(configuration.GetSection("MyList")) is IConfigurationSection section2) { List? temp4 = instance.MyList; temp4 ??= new List(); - BindCore(section2, ref temp4, binderOptions); + BindCore(section2, ref temp4, defaultValueIfNotFound: false, binderOptions); instance.MyList = temp4; } @@ -109,7 +116,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { Dictionary? temp7 = instance.MyDictionary; temp7 ??= new Dictionary(); - BindCore(section5, ref temp7, binderOptions); + BindCore(section5, ref temp7, defaultValueIfNotFound: false, binderOptions); instance.MyDictionary = temp7; } @@ -117,7 +124,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { Dictionary? temp10 = instance.MyComplexDictionary; temp10 ??= new Dictionary(); - BindCore(section8, ref temp10, binderOptions); + BindCore(section8, ref temp10, defaultValueIfNotFound: false, binderOptions); instance.MyComplexDictionary = temp10; } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Bind_Key_Instance.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Bind_Key_Instance.generated.txt index 392533daea462..89b82d31bc19a 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Bind_Key_Instance.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Bind_Key_Instance.generated.txt @@ -45,14 +45,14 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration } var typedObj = (Program.MyClass)instance; - BindCore(configuration.GetSection(key), ref typedObj, binderOptions: null); + BindCore(configuration.GetSection(key), ref typedObj, defaultValueIfNotFound: false, binderOptions: null); } #endregion IConfiguration extensions. #region Core binding extensions. private readonly static Lazy> s_configKeys_ProgramMyClass = new(() => new HashSet(StringComparer.OrdinalIgnoreCase) { "MyString", "MyInt", "MyList", "MyDictionary", "MyComplexDictionary" }); - public static void BindCore(IConfiguration configuration, ref List instance, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref List instance, bool defaultValueIfNotFound, BinderOptions? binderOptions) { foreach (IConfigurationSection section in configuration.GetChildren()) { @@ -63,7 +63,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration } } - public static void BindCore(IConfiguration configuration, ref Dictionary instance, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref Dictionary instance, bool defaultValueIfNotFound, BinderOptions? binderOptions) { foreach (IConfigurationSection section in configuration.GetChildren()) { @@ -74,7 +74,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration } } - public static void BindCore(IConfiguration configuration, ref Dictionary instance, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref Dictionary instance, bool defaultValueIfNotFound, BinderOptions? binderOptions) { foreach (IConfigurationSection section in configuration.GetChildren()) { @@ -86,22 +86,29 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration } } - public static void BindCore(IConfiguration configuration, ref Program.MyClass instance, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref Program.MyClass instance, bool defaultValueIfNotFound, BinderOptions? binderOptions) { ValidateConfigurationKeys(typeof(Program.MyClass), s_configKeys_ProgramMyClass, configuration, binderOptions); - instance.MyString = configuration["MyString"]!; + if (configuration["MyString"] is string value0) + { + instance.MyString = value0; + } if (configuration["MyInt"] is string value1) { instance.MyInt = ParseInt(value1, () => configuration.GetSection("MyInt").Path); } + else if (defaultValueIfNotFound) + { + instance.MyInt = default; + } if (AsConfigWithChildren(configuration.GetSection("MyList")) is IConfigurationSection section2) { List? temp4 = instance.MyList; temp4 ??= new List(); - BindCore(section2, ref temp4, binderOptions); + BindCore(section2, ref temp4, defaultValueIfNotFound: false, binderOptions); instance.MyList = temp4; } @@ -109,7 +116,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { Dictionary? temp7 = instance.MyDictionary; temp7 ??= new Dictionary(); - BindCore(section5, ref temp7, binderOptions); + BindCore(section5, ref temp7, defaultValueIfNotFound: false, binderOptions); instance.MyDictionary = temp7; } @@ -117,7 +124,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { Dictionary? temp10 = instance.MyComplexDictionary; temp10 ??= new Dictionary(); - BindCore(section8, ref temp10, binderOptions); + BindCore(section8, ref temp10, defaultValueIfNotFound: false, binderOptions); instance.MyComplexDictionary = temp10; } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Get.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Get.generated.txt index d0faaa8fc9151..5e7eeae29254a 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Get.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Get.generated.txt @@ -68,20 +68,20 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration if (type == typeof(Program.MyClass)) { var instance = new Program.MyClass(); - BindCore(configuration, ref instance, binderOptions); + BindCore(configuration, ref instance, defaultValueIfNotFound: true, binderOptions); return instance; } else if (type == typeof(Program.MyClass2)) { var instance = new Program.MyClass2(); - BindCore(configuration, ref instance, binderOptions); + BindCore(configuration, ref instance, defaultValueIfNotFound: true, binderOptions); return instance; } throw new NotSupportedException($"Unable to bind to type '{type}': generator did not detect the type as input."); } - public static void BindCore(IConfiguration configuration, ref List instance, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref List instance, bool defaultValueIfNotFound, BinderOptions? binderOptions) { foreach (IConfigurationSection section in configuration.GetChildren()) { @@ -92,16 +92,16 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration } } - public static void BindCore(IConfiguration configuration, ref int[] instance, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref int[] instance, bool defaultValueIfNotFound, BinderOptions? binderOptions) { var temp2 = new List(); - BindCore(configuration, ref temp2, binderOptions); + BindCore(configuration, ref temp2, defaultValueIfNotFound: false, binderOptions); int originalCount = instance.Length; Array.Resize(ref instance, originalCount + temp2.Count); temp2.CopyTo(instance, originalCount); } - public static void BindCore(IConfiguration configuration, ref Dictionary instance, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref Dictionary instance, bool defaultValueIfNotFound, BinderOptions? binderOptions) { foreach (IConfigurationSection section in configuration.GetChildren()) { @@ -112,22 +112,29 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration } } - public static void BindCore(IConfiguration configuration, ref Program.MyClass instance, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref Program.MyClass instance, bool defaultValueIfNotFound, BinderOptions? binderOptions) { ValidateConfigurationKeys(typeof(Program.MyClass), s_configKeys_ProgramMyClass, configuration, binderOptions); - instance.MyString = configuration["MyString"]!; + if (configuration["MyString"] is string value4) + { + instance.MyString = value4; + } if (configuration["MyInt"] is string value5) { instance.MyInt = ParseInt(value5, () => configuration.GetSection("MyInt").Path); } + else if (defaultValueIfNotFound) + { + instance.MyInt = default; + } if (AsConfigWithChildren(configuration.GetSection("MyList")) is IConfigurationSection section6) { List? temp8 = instance.MyList; temp8 ??= new List(); - BindCore(section6, ref temp8, binderOptions); + BindCore(section6, ref temp8, defaultValueIfNotFound: false, binderOptions); instance.MyList = temp8; } @@ -135,7 +142,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { int[]? temp11 = instance.MyArray; temp11 ??= new int[0]; - BindCore(section9, ref temp11, binderOptions); + BindCore(section9, ref temp11, defaultValueIfNotFound: false, binderOptions); instance.MyArray = temp11; } @@ -143,12 +150,12 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { Dictionary? temp14 = instance.MyDictionary; temp14 ??= new Dictionary(); - BindCore(section12, ref temp14, binderOptions); + BindCore(section12, ref temp14, defaultValueIfNotFound: false, binderOptions); instance.MyDictionary = temp14; } } - public static void BindCore(IConfiguration configuration, ref Program.MyClass2 instance, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref Program.MyClass2 instance, bool defaultValueIfNotFound, BinderOptions? binderOptions) { ValidateConfigurationKeys(typeof(Program.MyClass2), s_configKeys_ProgramMyClass2, configuration, binderOptions); @@ -156,6 +163,10 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { instance.MyInt = ParseInt(value15, () => configuration.GetSection("MyInt").Path); } + else if (defaultValueIfNotFound) + { + instance.MyInt = default; + } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Get_T.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Get_T.generated.txt index 0b7031b1da00b..3fc5176bf50f0 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Get_T.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Get_T.generated.txt @@ -55,14 +55,14 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration if (type == typeof(Program.MyClass)) { var instance = new Program.MyClass(); - BindCore(configuration, ref instance, binderOptions); + BindCore(configuration, ref instance, defaultValueIfNotFound: true, binderOptions); return instance; } throw new NotSupportedException($"Unable to bind to type '{type}': generator did not detect the type as input."); } - public static void BindCore(IConfiguration configuration, ref List instance, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref List instance, bool defaultValueIfNotFound, BinderOptions? binderOptions) { foreach (IConfigurationSection section in configuration.GetChildren()) { @@ -73,16 +73,16 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration } } - public static void BindCore(IConfiguration configuration, ref int[] instance, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref int[] instance, bool defaultValueIfNotFound, BinderOptions? binderOptions) { var temp1 = new List(); - BindCore(configuration, ref temp1, binderOptions); + BindCore(configuration, ref temp1, defaultValueIfNotFound: false, binderOptions); int originalCount = instance.Length; Array.Resize(ref instance, originalCount + temp1.Count); temp1.CopyTo(instance, originalCount); } - public static void BindCore(IConfiguration configuration, ref Dictionary instance, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref Dictionary instance, bool defaultValueIfNotFound, BinderOptions? binderOptions) { foreach (IConfigurationSection section in configuration.GetChildren()) { @@ -93,22 +93,29 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration } } - public static void BindCore(IConfiguration configuration, ref Program.MyClass instance, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref Program.MyClass instance, bool defaultValueIfNotFound, BinderOptions? binderOptions) { ValidateConfigurationKeys(typeof(Program.MyClass), s_configKeys_ProgramMyClass, configuration, binderOptions); - instance.MyString = configuration["MyString"]!; + if (configuration["MyString"] is string value3) + { + instance.MyString = value3; + } if (configuration["MyInt"] is string value4) { instance.MyInt = ParseInt(value4, () => configuration.GetSection("MyInt").Path); } + else if (defaultValueIfNotFound) + { + instance.MyInt = default; + } if (AsConfigWithChildren(configuration.GetSection("MyList")) is IConfigurationSection section5) { List? temp7 = instance.MyList; temp7 ??= new List(); - BindCore(section5, ref temp7, binderOptions); + BindCore(section5, ref temp7, defaultValueIfNotFound: false, binderOptions); instance.MyList = temp7; } @@ -116,7 +123,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { int[]? temp10 = instance.MyArray; temp10 ??= new int[0]; - BindCore(section8, ref temp10, binderOptions); + BindCore(section8, ref temp10, defaultValueIfNotFound: false, binderOptions); instance.MyArray = temp10; } @@ -124,7 +131,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { Dictionary? temp13 = instance.MyDictionary; temp13 ??= new Dictionary(); - BindCore(section11, ref temp13, binderOptions); + BindCore(section11, ref temp13, defaultValueIfNotFound: false, binderOptions); instance.MyDictionary = temp13; } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Get_T_BinderOptions.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Get_T_BinderOptions.generated.txt index 4c950a79266d1..81c23d7ceea65 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Get_T_BinderOptions.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Get_T_BinderOptions.generated.txt @@ -55,14 +55,14 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration if (type == typeof(Program.MyClass)) { var instance = new Program.MyClass(); - BindCore(configuration, ref instance, binderOptions); + BindCore(configuration, ref instance, defaultValueIfNotFound: true, binderOptions); return instance; } throw new NotSupportedException($"Unable to bind to type '{type}': generator did not detect the type as input."); } - public static void BindCore(IConfiguration configuration, ref List instance, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref List instance, bool defaultValueIfNotFound, BinderOptions? binderOptions) { foreach (IConfigurationSection section in configuration.GetChildren()) { @@ -73,16 +73,16 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration } } - public static void BindCore(IConfiguration configuration, ref int[] instance, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref int[] instance, bool defaultValueIfNotFound, BinderOptions? binderOptions) { var temp1 = new List(); - BindCore(configuration, ref temp1, binderOptions); + BindCore(configuration, ref temp1, defaultValueIfNotFound: false, binderOptions); int originalCount = instance.Length; Array.Resize(ref instance, originalCount + temp1.Count); temp1.CopyTo(instance, originalCount); } - public static void BindCore(IConfiguration configuration, ref Dictionary instance, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref Dictionary instance, bool defaultValueIfNotFound, BinderOptions? binderOptions) { foreach (IConfigurationSection section in configuration.GetChildren()) { @@ -93,22 +93,29 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration } } - public static void BindCore(IConfiguration configuration, ref Program.MyClass instance, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref Program.MyClass instance, bool defaultValueIfNotFound, BinderOptions? binderOptions) { ValidateConfigurationKeys(typeof(Program.MyClass), s_configKeys_ProgramMyClass, configuration, binderOptions); - instance.MyString = configuration["MyString"]!; + if (configuration["MyString"] is string value3) + { + instance.MyString = value3; + } if (configuration["MyInt"] is string value4) { instance.MyInt = ParseInt(value4, () => configuration.GetSection("MyInt").Path); } + else if (defaultValueIfNotFound) + { + instance.MyInt = default; + } if (AsConfigWithChildren(configuration.GetSection("MyList")) is IConfigurationSection section5) { List? temp7 = instance.MyList; temp7 ??= new List(); - BindCore(section5, ref temp7, binderOptions); + BindCore(section5, ref temp7, defaultValueIfNotFound: false, binderOptions); instance.MyList = temp7; } @@ -116,7 +123,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { int[]? temp10 = instance.MyArray; temp10 ??= new int[0]; - BindCore(section8, ref temp10, binderOptions); + BindCore(section8, ref temp10, defaultValueIfNotFound: false, binderOptions); instance.MyArray = temp10; } @@ -124,7 +131,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { Dictionary? temp13 = instance.MyDictionary; temp13 ??= new Dictionary(); - BindCore(section11, ref temp13, binderOptions); + BindCore(section11, ref temp13, defaultValueIfNotFound: false, binderOptions); instance.MyDictionary = temp13; } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Get_TypeOf.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Get_TypeOf.generated.txt index ca323c234b848..eca2001123ff0 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Get_TypeOf.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Get_TypeOf.generated.txt @@ -55,14 +55,14 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration if (type == typeof(Program.MyClass2)) { var instance = new Program.MyClass2(); - BindCore(configuration, ref instance, binderOptions); + BindCore(configuration, ref instance, defaultValueIfNotFound: true, binderOptions); return instance; } throw new NotSupportedException($"Unable to bind to type '{type}': generator did not detect the type as input."); } - public static void BindCore(IConfiguration configuration, ref Program.MyClass2 instance, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref Program.MyClass2 instance, bool defaultValueIfNotFound, BinderOptions? binderOptions) { ValidateConfigurationKeys(typeof(Program.MyClass2), s_configKeys_ProgramMyClass2, configuration, binderOptions); @@ -70,6 +70,10 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { instance.MyInt = ParseInt(value1, () => configuration.GetSection("MyInt").Path); } + else if (defaultValueIfNotFound) + { + instance.MyInt = default; + } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Get_TypeOf_BinderOptions.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Get_TypeOf_BinderOptions.generated.txt index e4a376a0cb325..7883f4a50da0f 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Get_TypeOf_BinderOptions.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Get_TypeOf_BinderOptions.generated.txt @@ -55,14 +55,14 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration if (type == typeof(Program.MyClass2)) { var instance = new Program.MyClass2(); - BindCore(configuration, ref instance, binderOptions); + BindCore(configuration, ref instance, defaultValueIfNotFound: true, binderOptions); return instance; } throw new NotSupportedException($"Unable to bind to type '{type}': generator did not detect the type as input."); } - public static void BindCore(IConfiguration configuration, ref Program.MyClass2 instance, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref Program.MyClass2 instance, bool defaultValueIfNotFound, BinderOptions? binderOptions) { ValidateConfigurationKeys(typeof(Program.MyClass2), s_configKeys_ProgramMyClass2, configuration, binderOptions); @@ -70,6 +70,10 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { instance.MyInt = ParseInt(value1, () => configuration.GetSection("MyInt").Path); } + else if (defaultValueIfNotFound) + { + instance.MyInt = default; + } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/EmptyConfigType.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/EmptyConfigType.generated.txt index c3db7a0ff408a..404ce7561cc47 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/EmptyConfigType.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/EmptyConfigType.generated.txt @@ -51,14 +51,14 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration } var typedObj = (TypeWithNoMembers_Wrapper)instance; - BindCore(configuration, ref typedObj, binderOptions: null); + BindCore(configuration, ref typedObj, defaultValueIfNotFound: false, binderOptions: null); } #endregion IConfiguration extensions. #region Core binding extensions. private readonly static Lazy> s_configKeys_TypeWithNoMembers_Wrapper = new(() => new HashSet(StringComparer.OrdinalIgnoreCase) { "Member" }); - public static void BindCore(IConfiguration configuration, ref TypeWithNoMembers_Wrapper instance, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref TypeWithNoMembers_Wrapper instance, bool defaultValueIfNotFound, BinderOptions? binderOptions) { ValidateConfigurationKeys(typeof(TypeWithNoMembers_Wrapper), s_configKeys_TypeWithNoMembers_Wrapper, configuration, binderOptions); diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/OptionsBuilder/BindConfiguration.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/OptionsBuilder/BindConfiguration.generated.txt index f3829683be2bb..44f1df2e78232 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/OptionsBuilder/BindConfiguration.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/OptionsBuilder/BindConfiguration.generated.txt @@ -82,14 +82,14 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration if (type == typeof(Program.MyClass)) { var temp = (Program.MyClass)instance; - BindCore(configuration, ref temp, binderOptions); + BindCore(configuration, ref temp, defaultValueIfNotFound: false, binderOptions); return; } throw new NotSupportedException($"Unable to bind to type '{type}': generator did not detect the type as input."); } - public static void BindCore(IConfiguration configuration, ref List instance, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref List instance, bool defaultValueIfNotFound, BinderOptions? binderOptions) { foreach (IConfigurationSection section in configuration.GetChildren()) { @@ -100,22 +100,29 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration } } - public static void BindCore(IConfiguration configuration, ref Program.MyClass instance, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref Program.MyClass instance, bool defaultValueIfNotFound, BinderOptions? binderOptions) { ValidateConfigurationKeys(typeof(Program.MyClass), s_configKeys_ProgramMyClass, configuration, binderOptions); - instance.MyString = configuration["MyString"]!; + if (configuration["MyString"] is string value1) + { + instance.MyString = value1; + } if (configuration["MyInt"] is string value2) { instance.MyInt = ParseInt(value2, () => configuration.GetSection("MyInt").Path); } + else if (defaultValueIfNotFound) + { + instance.MyInt = default; + } if (AsConfigWithChildren(configuration.GetSection("MyList")) is IConfigurationSection section3) { List? temp5 = instance.MyList; temp5 ??= new List(); - BindCore(section3, ref temp5, binderOptions); + BindCore(section3, ref temp5, defaultValueIfNotFound: false, binderOptions); instance.MyList = temp5; } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/OptionsBuilder/Bind_T.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/OptionsBuilder/Bind_T.generated.txt index de6ea5a3b9e1c..8d7c70a27b3f2 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/OptionsBuilder/Bind_T.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/OptionsBuilder/Bind_T.generated.txt @@ -92,14 +92,14 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration if (type == typeof(Program.MyClass)) { var temp = (Program.MyClass)instance; - BindCore(configuration, ref temp, binderOptions); + BindCore(configuration, ref temp, defaultValueIfNotFound: false, binderOptions); return; } throw new NotSupportedException($"Unable to bind to type '{type}': generator did not detect the type as input."); } - public static void BindCore(IConfiguration configuration, ref List instance, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref List instance, bool defaultValueIfNotFound, BinderOptions? binderOptions) { foreach (IConfigurationSection section in configuration.GetChildren()) { @@ -110,22 +110,29 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration } } - public static void BindCore(IConfiguration configuration, ref Program.MyClass instance, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref Program.MyClass instance, bool defaultValueIfNotFound, BinderOptions? binderOptions) { ValidateConfigurationKeys(typeof(Program.MyClass), s_configKeys_ProgramMyClass, configuration, binderOptions); - instance.MyString = configuration["MyString"]!; + if (configuration["MyString"] is string value1) + { + instance.MyString = value1; + } if (configuration["MyInt"] is string value2) { instance.MyInt = ParseInt(value2, () => configuration.GetSection("MyInt").Path); } + else if (defaultValueIfNotFound) + { + instance.MyInt = default; + } if (AsConfigWithChildren(configuration.GetSection("MyList")) is IConfigurationSection section3) { List? temp5 = instance.MyList; temp5 ??= new List(); - BindCore(section3, ref temp5, binderOptions); + BindCore(section3, ref temp5, defaultValueIfNotFound: false, binderOptions); instance.MyList = temp5; } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/OptionsBuilder/Bind_T_BinderOptions.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/OptionsBuilder/Bind_T_BinderOptions.generated.txt index 2c40ebf69c9b4..385079af1709a 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/OptionsBuilder/Bind_T_BinderOptions.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/OptionsBuilder/Bind_T_BinderOptions.generated.txt @@ -86,14 +86,14 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration if (type == typeof(Program.MyClass)) { var temp = (Program.MyClass)instance; - BindCore(configuration, ref temp, binderOptions); + BindCore(configuration, ref temp, defaultValueIfNotFound: false, binderOptions); return; } throw new NotSupportedException($"Unable to bind to type '{type}': generator did not detect the type as input."); } - public static void BindCore(IConfiguration configuration, ref List instance, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref List instance, bool defaultValueIfNotFound, BinderOptions? binderOptions) { foreach (IConfigurationSection section in configuration.GetChildren()) { @@ -104,22 +104,29 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration } } - public static void BindCore(IConfiguration configuration, ref Program.MyClass instance, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref Program.MyClass instance, bool defaultValueIfNotFound, BinderOptions? binderOptions) { ValidateConfigurationKeys(typeof(Program.MyClass), s_configKeys_ProgramMyClass, configuration, binderOptions); - instance.MyString = configuration["MyString"]!; + if (configuration["MyString"] is string value1) + { + instance.MyString = value1; + } if (configuration["MyInt"] is string value2) { instance.MyInt = ParseInt(value2, () => configuration.GetSection("MyInt").Path); } + else if (defaultValueIfNotFound) + { + instance.MyInt = default; + } if (AsConfigWithChildren(configuration.GetSection("MyList")) is IConfigurationSection section3) { List? temp5 = instance.MyList; temp5 ??= new List(); - BindCore(section3, ref temp5, binderOptions); + BindCore(section3, ref temp5, defaultValueIfNotFound: false, binderOptions); instance.MyList = temp5; } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/Primitives.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/Primitives.generated.txt index 7d94145d42a51..a8373ca527095 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/Primitives.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/Primitives.generated.txt @@ -45,14 +45,14 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration } var typedObj = (Program.MyClass)instance; - BindCore(configuration, ref typedObj, binderOptions: null); + BindCore(configuration, ref typedObj, defaultValueIfNotFound: false, binderOptions: null); } #endregion IConfiguration extensions. #region Core binding extensions. private readonly static Lazy> s_configKeys_ProgramMyClass = new(() => new HashSet(StringComparer.OrdinalIgnoreCase) { "Prop0", "Prop1", "Prop2", "Prop3", "Prop4", "Prop5", "Prop6", "Prop8", "Prop9", "Prop10", "Prop13", "Prop14", "Prop15", "Prop16", "Prop17", "Prop19", "Prop20", "Prop21", "Prop23", "Prop24", "Prop25", "Prop26", "Prop27", "Prop7", "Prop11", "Prop12", "Prop18", "Prop22", "Prop28", "Prop29", "Prop30" }); - public static void BindCore(IConfiguration configuration, ref Program.MyClass instance, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref Program.MyClass instance, bool defaultValueIfNotFound, BinderOptions? binderOptions) { ValidateConfigurationKeys(typeof(Program.MyClass), s_configKeys_ProgramMyClass, configuration, binderOptions); @@ -60,65 +60,119 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { instance.Prop0 = ParseBool(value0, () => configuration.GetSection("Prop0").Path); } + else if (defaultValueIfNotFound) + { + instance.Prop0 = default; + } if (configuration["Prop1"] is string value1) { instance.Prop1 = ParseByte(value1, () => configuration.GetSection("Prop1").Path); } + else if (defaultValueIfNotFound) + { + instance.Prop1 = default; + } if (configuration["Prop2"] is string value2) { instance.Prop2 = ParseSbyte(value2, () => configuration.GetSection("Prop2").Path); } + else if (defaultValueIfNotFound) + { + instance.Prop2 = default; + } if (configuration["Prop3"] is string value3) { instance.Prop3 = ParseChar(value3, () => configuration.GetSection("Prop3").Path); } + else if (defaultValueIfNotFound) + { + instance.Prop3 = default; + } if (configuration["Prop4"] is string value4) { instance.Prop4 = ParseDouble(value4, () => configuration.GetSection("Prop4").Path); } + else if (defaultValueIfNotFound) + { + instance.Prop4 = default; + } - instance.Prop5 = configuration["Prop5"]!; + if (configuration["Prop5"] is string value5) + { + instance.Prop5 = value5; + } if (configuration["Prop6"] is string value6) { instance.Prop6 = ParseInt(value6, () => configuration.GetSection("Prop6").Path); } + else if (defaultValueIfNotFound) + { + instance.Prop6 = default; + } if (configuration["Prop8"] is string value7) { instance.Prop8 = ParseShort(value7, () => configuration.GetSection("Prop8").Path); } + else if (defaultValueIfNotFound) + { + instance.Prop8 = default; + } if (configuration["Prop9"] is string value8) { instance.Prop9 = ParseLong(value8, () => configuration.GetSection("Prop9").Path); } + else if (defaultValueIfNotFound) + { + instance.Prop9 = default; + } if (configuration["Prop10"] is string value9) { instance.Prop10 = ParseFloat(value9, () => configuration.GetSection("Prop10").Path); } + else if (defaultValueIfNotFound) + { + instance.Prop10 = default; + } if (configuration["Prop13"] is string value10) { instance.Prop13 = ParseUshort(value10, () => configuration.GetSection("Prop13").Path); } + else if (defaultValueIfNotFound) + { + instance.Prop13 = default; + } if (configuration["Prop14"] is string value11) { instance.Prop14 = ParseUint(value11, () => configuration.GetSection("Prop14").Path); } + else if (defaultValueIfNotFound) + { + instance.Prop14 = default; + } if (configuration["Prop15"] is string value12) { instance.Prop15 = ParseUlong(value12, () => configuration.GetSection("Prop15").Path); } + else if (defaultValueIfNotFound) + { + instance.Prop15 = default; + } - instance.Prop16 = configuration["Prop16"]!; + if (configuration["Prop16"] is string value13) + { + instance.Prop16 = value13; + } if (configuration["Prop17"] is string value14) { @@ -129,26 +183,46 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { instance.Prop19 = ParseDateTime(value15, () => configuration.GetSection("Prop19").Path); } + else if (defaultValueIfNotFound) + { + instance.Prop19 = default; + } if (configuration["Prop20"] is string value16) { instance.Prop20 = ParseDateTimeOffset(value16, () => configuration.GetSection("Prop20").Path); } + else if (defaultValueIfNotFound) + { + instance.Prop20 = default; + } if (configuration["Prop21"] is string value17) { instance.Prop21 = ParseDecimal(value17, () => configuration.GetSection("Prop21").Path); } + else if (defaultValueIfNotFound) + { + instance.Prop21 = default; + } if (configuration["Prop23"] is string value18) { instance.Prop23 = ParseTimeSpan(value18, () => configuration.GetSection("Prop23").Path); } + else if (defaultValueIfNotFound) + { + instance.Prop23 = default; + } if (configuration["Prop24"] is string value19) { instance.Prop24 = ParseGuid(value19, () => configuration.GetSection("Prop24").Path); } + else if (defaultValueIfNotFound) + { + instance.Prop24 = default; + } if (configuration["Prop25"] is string value20) { @@ -164,31 +238,55 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { instance.Prop27 = ParseEnum(value22, () => configuration.GetSection("Prop27").Path); } + else if (defaultValueIfNotFound) + { + instance.Prop27 = default; + } if (configuration["Prop7"] is string value23) { instance.Prop7 = ParseInt128(value23, () => configuration.GetSection("Prop7").Path); } + else if (defaultValueIfNotFound) + { + instance.Prop7 = default; + } if (configuration["Prop11"] is string value24) { instance.Prop11 = ParseHalf(value24, () => configuration.GetSection("Prop11").Path); } + else if (defaultValueIfNotFound) + { + instance.Prop11 = default; + } if (configuration["Prop12"] is string value25) { instance.Prop12 = ParseUInt128(value25, () => configuration.GetSection("Prop12").Path); } + else if (defaultValueIfNotFound) + { + instance.Prop12 = default; + } if (configuration["Prop18"] is string value26) { instance.Prop18 = ParseDateOnly(value26, () => configuration.GetSection("Prop18").Path); } + else if (defaultValueIfNotFound) + { + instance.Prop18 = default; + } if (configuration["Prop22"] is string value27) { instance.Prop22 = ParseTimeOnly(value27, () => configuration.GetSection("Prop22").Path); } + else if (defaultValueIfNotFound) + { + instance.Prop22 = default; + } if (configuration["Prop28"] is string value28) { @@ -199,11 +297,19 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { instance.Prop29 = ParseInt(value29, () => configuration.GetSection("Prop29").Path); } + else if (defaultValueIfNotFound) + { + instance.Prop29 = default; + } if (configuration["Prop30"] is string value30) { instance.Prop30 = ParseDateTime(value30, () => configuration.GetSection("Prop30").Path); } + else if (defaultValueIfNotFound) + { + instance.Prop30 = default; + } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ServiceCollection/Configure_T.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ServiceCollection/Configure_T.generated.txt index 973895e09fe55..3e38a484c8255 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ServiceCollection/Configure_T.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ServiceCollection/Configure_T.generated.txt @@ -79,14 +79,14 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration if (type == typeof(Program.MyClass)) { var temp = (Program.MyClass)instance; - BindCore(configuration, ref temp, binderOptions); + BindCore(configuration, ref temp, defaultValueIfNotFound: false, binderOptions); return; } throw new NotSupportedException($"Unable to bind to type '{type}': generator did not detect the type as input."); } - public static void BindCore(IConfiguration configuration, ref List instance, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref List instance, bool defaultValueIfNotFound, BinderOptions? binderOptions) { foreach (IConfigurationSection section in configuration.GetChildren()) { @@ -97,7 +97,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration } } - public static void BindCore(IConfiguration configuration, ref Program.MyClass2 instance, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref Program.MyClass2 instance, bool defaultValueIfNotFound, BinderOptions? binderOptions) { ValidateConfigurationKeys(typeof(Program.MyClass2), s_configKeys_ProgramMyClass2, configuration, binderOptions); @@ -105,19 +105,23 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { instance.MyInt = ParseInt(value1, () => configuration.GetSection("MyInt").Path); } + else if (defaultValueIfNotFound) + { + instance.MyInt = default; + } } - public static void BindCore(IConfiguration configuration, ref List instance, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref List instance, bool defaultValueIfNotFound, BinderOptions? binderOptions) { foreach (IConfigurationSection section in configuration.GetChildren()) { var value = new Program.MyClass2(); - BindCore(section, ref value, binderOptions); + BindCore(section, ref value, defaultValueIfNotFound: false, binderOptions); instance.Add(value); } } - public static void BindCore(IConfiguration configuration, ref Dictionary instance, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref Dictionary instance, bool defaultValueIfNotFound, BinderOptions? binderOptions) { foreach (IConfigurationSection section in configuration.GetChildren()) { @@ -128,22 +132,29 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration } } - public static void BindCore(IConfiguration configuration, ref Program.MyClass instance, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref Program.MyClass instance, bool defaultValueIfNotFound, BinderOptions? binderOptions) { ValidateConfigurationKeys(typeof(Program.MyClass), s_configKeys_ProgramMyClass, configuration, binderOptions); - instance.MyString = configuration["MyString"]!; + if (configuration["MyString"] is string value3) + { + instance.MyString = value3; + } if (configuration["MyInt"] is string value4) { instance.MyInt = ParseInt(value4, () => configuration.GetSection("MyInt").Path); } + else if (defaultValueIfNotFound) + { + instance.MyInt = default; + } if (AsConfigWithChildren(configuration.GetSection("MyList")) is IConfigurationSection section5) { List? temp7 = instance.MyList; temp7 ??= new List(); - BindCore(section5, ref temp7, binderOptions); + BindCore(section5, ref temp7, defaultValueIfNotFound: false, binderOptions); instance.MyList = temp7; } @@ -151,7 +162,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { List? temp10 = instance.MyList2; temp10 ??= new List(); - BindCore(section8, ref temp10, binderOptions); + BindCore(section8, ref temp10, defaultValueIfNotFound: false, binderOptions); instance.MyList2 = temp10; } @@ -159,7 +170,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { Dictionary? temp13 = instance.MyDictionary; temp13 ??= new Dictionary(); - BindCore(section11, ref temp13, binderOptions); + BindCore(section11, ref temp13, defaultValueIfNotFound: false, binderOptions); instance.MyDictionary = temp13; } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ServiceCollection/Configure_T_BinderOptions.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ServiceCollection/Configure_T_BinderOptions.generated.txt index 08f233aff5503..186e93a49207b 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ServiceCollection/Configure_T_BinderOptions.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ServiceCollection/Configure_T_BinderOptions.generated.txt @@ -79,14 +79,14 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration if (type == typeof(Program.MyClass)) { var temp = (Program.MyClass)instance; - BindCore(configuration, ref temp, binderOptions); + BindCore(configuration, ref temp, defaultValueIfNotFound: false, binderOptions); return; } throw new NotSupportedException($"Unable to bind to type '{type}': generator did not detect the type as input."); } - public static void BindCore(IConfiguration configuration, ref List instance, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref List instance, bool defaultValueIfNotFound, BinderOptions? binderOptions) { foreach (IConfigurationSection section in configuration.GetChildren()) { @@ -97,7 +97,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration } } - public static void BindCore(IConfiguration configuration, ref Program.MyClass2 instance, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref Program.MyClass2 instance, bool defaultValueIfNotFound, BinderOptions? binderOptions) { ValidateConfigurationKeys(typeof(Program.MyClass2), s_configKeys_ProgramMyClass2, configuration, binderOptions); @@ -105,19 +105,23 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { instance.MyInt = ParseInt(value1, () => configuration.GetSection("MyInt").Path); } + else if (defaultValueIfNotFound) + { + instance.MyInt = default; + } } - public static void BindCore(IConfiguration configuration, ref List instance, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref List instance, bool defaultValueIfNotFound, BinderOptions? binderOptions) { foreach (IConfigurationSection section in configuration.GetChildren()) { var value = new Program.MyClass2(); - BindCore(section, ref value, binderOptions); + BindCore(section, ref value, defaultValueIfNotFound: false, binderOptions); instance.Add(value); } } - public static void BindCore(IConfiguration configuration, ref Dictionary instance, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref Dictionary instance, bool defaultValueIfNotFound, BinderOptions? binderOptions) { foreach (IConfigurationSection section in configuration.GetChildren()) { @@ -128,22 +132,29 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration } } - public static void BindCore(IConfiguration configuration, ref Program.MyClass instance, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref Program.MyClass instance, bool defaultValueIfNotFound, BinderOptions? binderOptions) { ValidateConfigurationKeys(typeof(Program.MyClass), s_configKeys_ProgramMyClass, configuration, binderOptions); - instance.MyString = configuration["MyString"]!; + if (configuration["MyString"] is string value3) + { + instance.MyString = value3; + } if (configuration["MyInt"] is string value4) { instance.MyInt = ParseInt(value4, () => configuration.GetSection("MyInt").Path); } + else if (defaultValueIfNotFound) + { + instance.MyInt = default; + } if (AsConfigWithChildren(configuration.GetSection("MyList")) is IConfigurationSection section5) { List? temp7 = instance.MyList; temp7 ??= new List(); - BindCore(section5, ref temp7, binderOptions); + BindCore(section5, ref temp7, defaultValueIfNotFound: false, binderOptions); instance.MyList = temp7; } @@ -151,7 +162,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { List? temp10 = instance.MyList2; temp10 ??= new List(); - BindCore(section8, ref temp10, binderOptions); + BindCore(section8, ref temp10, defaultValueIfNotFound: false, binderOptions); instance.MyList2 = temp10; } @@ -159,7 +170,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { Dictionary? temp13 = instance.MyDictionary; temp13 ??= new Dictionary(); - BindCore(section11, ref temp13, binderOptions); + BindCore(section11, ref temp13, defaultValueIfNotFound: false, binderOptions); instance.MyDictionary = temp13; } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ServiceCollection/Configure_T_name.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ServiceCollection/Configure_T_name.generated.txt index cb41ea860980a..7958adb112533 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ServiceCollection/Configure_T_name.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ServiceCollection/Configure_T_name.generated.txt @@ -79,14 +79,14 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration if (type == typeof(Program.MyClass)) { var temp = (Program.MyClass)instance; - BindCore(configuration, ref temp, binderOptions); + BindCore(configuration, ref temp, defaultValueIfNotFound: false, binderOptions); return; } throw new NotSupportedException($"Unable to bind to type '{type}': generator did not detect the type as input."); } - public static void BindCore(IConfiguration configuration, ref List instance, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref List instance, bool defaultValueIfNotFound, BinderOptions? binderOptions) { foreach (IConfigurationSection section in configuration.GetChildren()) { @@ -97,7 +97,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration } } - public static void BindCore(IConfiguration configuration, ref Program.MyClass2 instance, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref Program.MyClass2 instance, bool defaultValueIfNotFound, BinderOptions? binderOptions) { ValidateConfigurationKeys(typeof(Program.MyClass2), s_configKeys_ProgramMyClass2, configuration, binderOptions); @@ -105,19 +105,23 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { instance.MyInt = ParseInt(value1, () => configuration.GetSection("MyInt").Path); } + else if (defaultValueIfNotFound) + { + instance.MyInt = default; + } } - public static void BindCore(IConfiguration configuration, ref List instance, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref List instance, bool defaultValueIfNotFound, BinderOptions? binderOptions) { foreach (IConfigurationSection section in configuration.GetChildren()) { var value = new Program.MyClass2(); - BindCore(section, ref value, binderOptions); + BindCore(section, ref value, defaultValueIfNotFound: false, binderOptions); instance.Add(value); } } - public static void BindCore(IConfiguration configuration, ref Dictionary instance, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref Dictionary instance, bool defaultValueIfNotFound, BinderOptions? binderOptions) { foreach (IConfigurationSection section in configuration.GetChildren()) { @@ -128,22 +132,29 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration } } - public static void BindCore(IConfiguration configuration, ref Program.MyClass instance, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref Program.MyClass instance, bool defaultValueIfNotFound, BinderOptions? binderOptions) { ValidateConfigurationKeys(typeof(Program.MyClass), s_configKeys_ProgramMyClass, configuration, binderOptions); - instance.MyString = configuration["MyString"]!; + if (configuration["MyString"] is string value3) + { + instance.MyString = value3; + } if (configuration["MyInt"] is string value4) { instance.MyInt = ParseInt(value4, () => configuration.GetSection("MyInt").Path); } + else if (defaultValueIfNotFound) + { + instance.MyInt = default; + } if (AsConfigWithChildren(configuration.GetSection("MyList")) is IConfigurationSection section5) { List? temp7 = instance.MyList; temp7 ??= new List(); - BindCore(section5, ref temp7, binderOptions); + BindCore(section5, ref temp7, defaultValueIfNotFound: false, binderOptions); instance.MyList = temp7; } @@ -151,7 +162,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { List? temp10 = instance.MyList2; temp10 ??= new List(); - BindCore(section8, ref temp10, binderOptions); + BindCore(section8, ref temp10, defaultValueIfNotFound: false, binderOptions); instance.MyList2 = temp10; } @@ -159,7 +170,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { Dictionary? temp13 = instance.MyDictionary; temp13 ??= new Dictionary(); - BindCore(section11, ref temp13, binderOptions); + BindCore(section11, ref temp13, defaultValueIfNotFound: false, binderOptions); instance.MyDictionary = temp13; } } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ServiceCollection/Configure_T_name_BinderOptions.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ServiceCollection/Configure_T_name_BinderOptions.generated.txt index 0a5e5a7ff6d26..b87d0c0a259cc 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ServiceCollection/Configure_T_name_BinderOptions.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ServiceCollection/Configure_T_name_BinderOptions.generated.txt @@ -73,14 +73,14 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration if (type == typeof(Program.MyClass)) { var temp = (Program.MyClass)instance; - BindCore(configuration, ref temp, binderOptions); + BindCore(configuration, ref temp, defaultValueIfNotFound: false, binderOptions); return; } throw new NotSupportedException($"Unable to bind to type '{type}': generator did not detect the type as input."); } - public static void BindCore(IConfiguration configuration, ref List instance, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref List instance, bool defaultValueIfNotFound, BinderOptions? binderOptions) { foreach (IConfigurationSection section in configuration.GetChildren()) { @@ -91,7 +91,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration } } - public static void BindCore(IConfiguration configuration, ref Program.MyClass2 instance, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref Program.MyClass2 instance, bool defaultValueIfNotFound, BinderOptions? binderOptions) { ValidateConfigurationKeys(typeof(Program.MyClass2), s_configKeys_ProgramMyClass2, configuration, binderOptions); @@ -99,19 +99,23 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { instance.MyInt = ParseInt(value1, () => configuration.GetSection("MyInt").Path); } + else if (defaultValueIfNotFound) + { + instance.MyInt = default; + } } - public static void BindCore(IConfiguration configuration, ref List instance, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref List instance, bool defaultValueIfNotFound, BinderOptions? binderOptions) { foreach (IConfigurationSection section in configuration.GetChildren()) { var value = new Program.MyClass2(); - BindCore(section, ref value, binderOptions); + BindCore(section, ref value, defaultValueIfNotFound: false, binderOptions); instance.Add(value); } } - public static void BindCore(IConfiguration configuration, ref Dictionary instance, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref Dictionary instance, bool defaultValueIfNotFound, BinderOptions? binderOptions) { foreach (IConfigurationSection section in configuration.GetChildren()) { @@ -122,22 +126,29 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration } } - public static void BindCore(IConfiguration configuration, ref Program.MyClass instance, BinderOptions? binderOptions) + public static void BindCore(IConfiguration configuration, ref Program.MyClass instance, bool defaultValueIfNotFound, BinderOptions? binderOptions) { ValidateConfigurationKeys(typeof(Program.MyClass), s_configKeys_ProgramMyClass, configuration, binderOptions); - instance.MyString = configuration["MyString"]!; + if (configuration["MyString"] is string value3) + { + instance.MyString = value3; + } if (configuration["MyInt"] is string value4) { instance.MyInt = ParseInt(value4, () => configuration.GetSection("MyInt").Path); } + else if (defaultValueIfNotFound) + { + instance.MyInt = default; + } if (AsConfigWithChildren(configuration.GetSection("MyList")) is IConfigurationSection section5) { List? temp7 = instance.MyList; temp7 ??= new List(); - BindCore(section5, ref temp7, binderOptions); + BindCore(section5, ref temp7, defaultValueIfNotFound: false, binderOptions); instance.MyList = temp7; } @@ -145,7 +156,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { List? temp10 = instance.MyList2; temp10 ??= new List(); - BindCore(section8, ref temp10, binderOptions); + BindCore(section8, ref temp10, defaultValueIfNotFound: false, binderOptions); instance.MyList2 = temp10; } @@ -153,7 +164,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { Dictionary? temp13 = instance.MyDictionary; temp13 ??= new Dictionary(); - BindCore(section11, ref temp13, binderOptions); + BindCore(section11, ref temp13, defaultValueIfNotFound: false, binderOptions); instance.MyDictionary = temp13; } }