Skip to content

Commit

Permalink
Add individual compilation tests for each config binding overload (do…
Browse files Browse the repository at this point in the history
…tnet#86910)

* Add individual compilation tests for each config binding overload

* Update ConfigurationBindingGeneratorTests.cs

Restore exclusion of browser/wasm for test runs.
  • Loading branch information
layomia authored Jun 1, 2023
1 parent 71c9c73 commit b201698
Show file tree
Hide file tree
Showing 22 changed files with 2,245 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ private void EmitGetValueMethods()
if (_generationSpec.ShouldEmitMethods(BinderMethodSpecifier.GetValue_TypeOf_key_defaultValue))
{
EmitBlankLineIfRequired();
_writer.WriteLine($"public static object? {Identifier.GetValue}(this {FullyQualifiedDisplayName.IConfiguration} {Identifier.configuration}, {FullyQualifiedDisplayName.Type} {Identifier.type}, string {Identifier.key}, object? {Identifier.defaultValue}) =>" +
_writer.WriteLine($"public static object? {Identifier.GetValue}(this {FullyQualifiedDisplayName.IConfiguration} {Identifier.configuration}, {FullyQualifiedDisplayName.Type} {Identifier.type}, string {Identifier.key}, object? {Identifier.defaultValue}) => " +
$"{expressionForGetValueCore}({Identifier.configuration}, {Identifier.type}, {Identifier.key}) ?? {Identifier.defaultValue};");
}
}
Expand Down Expand Up @@ -527,7 +527,7 @@ private void EmitHelperMethods()
_precedingBlockExists = true;
}

if (_generationSpec.ShouldEmitMethods(BinderMethodSpecifier.RootMethodsWithConfigOptions))
if (_generationSpec.ShouldEmitMethods(BinderMethodSpecifier.MethodsThatAssessBinderOptions))
{
_writer.WriteBlankLine();
EmitGetBinderOptionsHelper();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ internal enum BinderMethodSpecifier
Bind = Bind_instance | Bind_instance_BinderOptions | Bind_key_instance,
Get = Get_T | Get_T_BinderOptions | Get_TypeOf | Get_TypeOf_BinderOptions,
GetValue = GetValue_T_key | GetValue_T_key_defaultValue | GetValue_TypeOf_key | GetValue_TypeOf_key_defaultValue,
RootMethodsWithConfigOptions = Bind_instance_BinderOptions | Get_T_BinderOptions | Get_TypeOf_BinderOptions,

MethodsThatAssessBinderOptions = Bind_instance_BinderOptions | Get
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
// <auto-generated/>
#nullable enable

internal static class GeneratedConfigurationBinder
{
public static void Bind(this global::Microsoft.Extensions.Configuration.IConfiguration configuration, global::Program.MyClass obj) => global::Microsoft.Extensions.Configuration.Binder.SourceGeneration.Helpers.BindCore(configuration, ref obj, binderOptions: null);
}

namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
{
using Microsoft.Extensions.Configuration;
using System;
using System.Collections.Generic;
using System.Globalization;

internal static class Helpers
{
public static void BindCore(IConfiguration configuration, ref List<int> obj, BinderOptions? binderOptions)
{
if (obj is null)
{
throw new ArgumentNullException(nameof(obj));
}

foreach (IConfigurationSection section in configuration.GetChildren())
{
int element;
if (section.Value is string stringValue0)
{
element = ParseInt(stringValue0, () => section.Path);
obj.Add(element);
}
}
}

public static void BindCore(IConfiguration configuration, ref Dictionary<string, string> obj, BinderOptions? binderOptions)
{
if (obj is null)
{
throw new ArgumentNullException(nameof(obj));
}

foreach (IConfigurationSection section in configuration.GetChildren())
{
string key = section.Key;
if (section.Value is string stringValue1)
{
obj[key] = stringValue1;
}
}
}

public static void BindCore(IConfiguration configuration, ref Program.MyClass2 obj, BinderOptions? binderOptions)
{
if (obj is null)
{
throw new ArgumentNullException(nameof(obj));
}

}

public static void BindCore(IConfiguration configuration, ref Dictionary<string, Program.MyClass2> obj, BinderOptions? binderOptions)
{
if (obj is null)
{
throw new ArgumentNullException(nameof(obj));
}

foreach (IConfigurationSection section in configuration.GetChildren())
{
string key = section.Key;
if (!(obj.TryGetValue(key, out Program.MyClass2? element) && element is not null))
{
element = new Program.MyClass2();
}
BindCore(section, ref element!, binderOptions);
obj[key] = element;
}
}

public static void BindCore(IConfiguration configuration, ref Program.MyClass obj, BinderOptions? binderOptions)
{
if (obj is null)
{
throw new ArgumentNullException(nameof(obj));
}

List<string>? temp = null;
foreach (IConfigurationSection section in configuration.GetChildren())
{
switch (section.Key)
{
case "MyString":
{
if (configuration["MyString"] is string stringValue3)
{
obj.MyString = stringValue3;
}
}
break;
case "MyInt":
{
if (configuration["MyInt"] is string stringValue4)
{
obj.MyInt = ParseInt(stringValue4, () => section.Path);
}
}
break;
case "MyList":
{
if (HasChildren(section))
{
List<int> temp5 = obj.MyList;
temp5 ??= new List<int>();
BindCore(section, ref temp5, binderOptions);
obj.MyList = temp5;
}
}
break;
case "MyDictionary":
{
if (HasChildren(section))
{
Dictionary<string, string> temp6 = obj.MyDictionary;
temp6 ??= new Dictionary<string, string>();
BindCore(section, ref temp6, binderOptions);
obj.MyDictionary = temp6;
}
}
break;
case "MyComplexDictionary":
{
if (HasChildren(section))
{
Dictionary<string, Program.MyClass2> temp7 = obj.MyComplexDictionary;
temp7 ??= new Dictionary<string, Program.MyClass2>();
BindCore(section, ref temp7, binderOptions);
obj.MyComplexDictionary = temp7;
}
}
break;
default:
{
if (binderOptions?.ErrorOnUnknownConfiguration == true)
{
(temp ??= new List<string>()).Add($"'{section.Key}'");
}
}
break;
}
}

if (temp is not null)
{
throw new InvalidOperationException($"'ErrorOnUnknownConfiguration' was set on the provided BinderOptions, but the following properties were not found on the instance of {typeof(Program.MyClass)}: {string.Join(", ", temp)}");
}
}

public static bool HasChildren(IConfiguration configuration)
{
foreach (IConfigurationSection section in configuration.GetChildren())
{
return true;
}
return false;
}

public static int ParseInt(string stringValue, Func<string?> getPath)
{
try
{
return int.Parse(stringValue, NumberStyles.Integer, CultureInfo.InvariantCulture);
}
catch (Exception exception)
{
throw new InvalidOperationException($"Failed to convert configuration value at '{getPath()}' to type '{typeof(int)}'.", exception);
}
}
}
}
Loading

0 comments on commit b201698

Please sign in to comment.