Skip to content

Commit

Permalink
Add binding against configuration section
Browse files Browse the repository at this point in the history
  • Loading branch information
rchoffardet committed Jul 22, 2024
1 parent 7e273c6 commit 350a54c
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,7 @@ private static void BindInstance(

var section = config as IConfigurationSection;
string? configValue = section?.Value;
if (configValue != null && TryConvertValue(type, configValue, section?.Path, out object? convertedValue, out Exception? error))
if (configValue != null && TryConvertStringValue(type, configValue, section?.Path, out object? convertedValue, out Exception? error))
{
if (error != null)
{
Expand All @@ -319,6 +319,17 @@ private static void BindInstance(
return;
}

if (section != null && TryConvertThroughTypeConvertValue(type, section, section.Path, out object? convertedValue2, out Exception? error2))
{
if(error2 != null)
{
throw error2;
}

bindingPoint.TrySetValue(convertedValue2);
return;
}

if (config.GetChildren().Any())
{
// for arrays and read-only list-like interfaces, we concatenate on to what is already there, if we can
Expand Down Expand Up @@ -861,7 +872,7 @@ private static Array BindArray(Type type, IEnumerable? source, IConfiguration co
}

[RequiresUnreferencedCode(TrimmingWarningMessage)]
private static bool TryConvertValue(
private static bool TryConvertStringValue(
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)]
Type type,
string value, string? path, out object? result, out Exception? error)
Expand All @@ -880,7 +891,7 @@ private static bool TryConvertValue(
{
return true;
}
return TryConvertValue(Nullable.GetUnderlyingType(type)!, value, path, out result, out error);
return TryConvertStringValue(Nullable.GetUnderlyingType(type)!, value, path, out result, out error);
}

TypeConverter converter = TypeDescriptor.GetConverter(type);
Expand Down Expand Up @@ -913,13 +924,39 @@ private static bool TryConvertValue(
return false;
}

[RequiresUnreferencedCode(TrimmingWarningMessage)]
private static bool TryConvertThroughTypeConvertValue(
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)]
Type type,
IConfigurationSection value, string? path, out object? result, out Exception? error)
{
error = null;
result = null;

TypeConverter converter = TypeDescriptor.GetConverter(type);
if (converter.CanConvertFrom(typeof(IConfigurationSection)))
{
try
{
result = converter.ConvertFrom(value);
}
catch (Exception ex)
{
error = new InvalidOperationException(SR.Format(SR.Error_FailedBinding, path, type), ex);
}
return true;
}

return false;
}

[RequiresUnreferencedCode(TrimmingWarningMessage)]
private static object? ConvertValue(
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)]
Type type,
string value, string? path)
{
TryConvertValue(type, value, path, out object? result, out Exception? error);
TryConvertStringValue(type, value, path, out object? result, out Exception? error);
if (error != null)
{
throw error;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1065,5 +1065,32 @@ public class DerivedClassWithHiddenMembers : IntermediateDerivedClass
public override int X { set => base.X = value + 1; }
}

[TypeConverter(typeof(ConvertingItemConverter))]
class ConvertingItem
{
public string Zero;
public string One;

public ConvertingItem(string firstParameter, string secondParameter)
{
Zero = firstParameter;
One = secondParameter;
}
}

class ConvertingItemConverter : TypeConverter
{
public override bool CanConvertFrom(ITypeDescriptorContext? context, Type sourceType)
{
return sourceType == typeof(IConfigurationSection);
}

public override object ConvertFrom(ITypeDescriptorContext? context, CultureInfo? culture, object value)
{
var section = (IConfigurationSection)value;
return new ConvertingItem(section.GetValue<string>("0"), section.GetValue<string>("1"));
}
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2581,5 +2581,28 @@ public void CanBindToClassWithNewProperties()
Assert.Equal(53, obj.X);
Assert.Equal(53, obj.XBase);
}

[Fact]
public void CanBindToClassWithTypeConverter()
{
var configuration = new ConfigurationBuilder()
.AddInMemoryCollection(new Dictionary<string, string>()
{
{ "Test:0", "Hello"},
{ "Test:1", "world"},
})
.Build();

try
{
var item = configuration.GetSection("Test").Get<ConvertingItem>();
Assert.Equal("Hello", item.Zero);
Assert.Equal("world", item.One);
}
catch (Exception e)
{
Assert.Fail(e.Message);
}
}
}
}

0 comments on commit 350a54c

Please sign in to comment.