Skip to content

Commit ead2d93

Browse files
Fix conversion to dictionary
1 parent f9ed0b9 commit ead2d93

File tree

1 file changed

+16
-19
lines changed

1 file changed

+16
-19
lines changed

src/Serilog.Settings.Configuration/Settings/Configuration/ObjectArgumentValue.cs

Lines changed: 16 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -79,15 +79,16 @@ bool TryCreateContainer([NotNullWhen(true)] out object? result)
7979
{
8080
result = null;
8181

82-
if (IsConstructableDictionary(toType, elementType, out var concreteType, out var addMethod))
82+
if (IsConstructableDictionary(toType, elementType, out var concreteType, out var keyType, out var valueType, out var addMethod))
8383
{
8484
result = Activator.CreateInstance(concreteType) ?? throw new InvalidOperationException($"Activator.CreateInstance returned null for {concreteType}");
8585

8686
foreach (var section in _section.GetChildren())
8787
{
8888
var argumentValue = ConfigurationReader.GetArgumentValue(section, _configurationAssemblies);
89-
var value = argumentValue.ConvertTo(elementType, resolutionContext);
90-
addMethod.Invoke(result, new[] { section.Key, value });
89+
var key = new StringArgumentValue(section.Key).ConvertTo(keyType, resolutionContext);
90+
var value = argumentValue.ConvertTo(valueType, resolutionContext);
91+
addMethod.Invoke(result, new[] { key, value });
9192
}
9293
return true;
9394
}
@@ -262,21 +263,23 @@ static bool TryBindToCtorArgument(object value, Type type, ResolutionContext res
262263
{
263264
argumentExpression = Expression.Convert(ctorExpression, type);
264265
}
265-
else {
266+
else
267+
{
266268
argumentExpression = ctorExpression;
267269
}
268270
return true;
269271
}
270272
if (IsContainer(type, out elementType))
271273
{
272-
if (IsConstructableDictionary(type, elementType, out var concreteType, out var addMethod))
274+
if (IsConstructableDictionary(type, elementType, out var concreteType, out var keyType, out var valueType, out var addMethod))
273275
{
274276
var elements = new List<ElementInit>();
275277
foreach (var element in s.GetChildren())
276278
{
277-
if (TryBindToCtorArgument(element, elementType, resolutionContext, out var elementExpression))
279+
if (TryBindToCtorArgument(element, valueType, resolutionContext, out var elementExpression))
278280
{
279-
elements.Add(Expression.ElementInit(addMethod, Expression.Constant(element.Key), elementExpression));
281+
var key = new StringArgumentValue(element.Key).ConvertTo(keyType, resolutionContext);
282+
elements.Add(Expression.ElementInit(addMethod, Expression.Constant(key, keyType), elementExpression));
280283
}
281284
else
282285
{
@@ -337,24 +340,19 @@ static bool IsContainer(Type type, [NotNullWhen(true)] out Type? elementType)
337340
return false;
338341
}
339342

340-
static bool IsConstructableDictionary(Type type, Type elementType, [NotNullWhen(true)] out Type? concreteType, [NotNullWhen(true)] out MethodInfo? addMethod)
343+
static bool IsConstructableDictionary(Type type, Type elementType, [NotNullWhen(true)] out Type? concreteType, [NotNullWhen(true)] out Type? keyType, [NotNullWhen(true)] out Type? valueType, [NotNullWhen(true)] out MethodInfo? addMethod)
341344
{
342345
concreteType = null;
346+
keyType = null;
347+
valueType = null;
343348
addMethod = null;
344349
if (!elementType.IsGenericType || elementType.GetGenericTypeDefinition() != typeof(KeyValuePair<,>))
345350
{
346351
return false;
347352
}
348353
var argumentTypes = elementType.GetGenericArguments();
349-
if (argumentTypes[0] != typeof(string))
350-
{
351-
return false;
352-
}
353-
if (!typeof(IDictionary<,>).MakeGenericType(argumentTypes).IsAssignableFrom(type)
354-
&& !typeof(IReadOnlyDictionary<,>).MakeGenericType(argumentTypes).IsAssignableFrom(type))
355-
{
356-
return false;
357-
}
354+
keyType = argumentTypes[0];
355+
valueType = argumentTypes[1];
358356
if (type.IsAbstract)
359357
{
360358
concreteType = typeof(Dictionary<,>).MakeGenericType(argumentTypes);
@@ -371,13 +369,12 @@ static bool IsConstructableDictionary(Type type, Type elementType, [NotNullWhen(
371369
{
372370
return false;
373371
}
374-
var valueType = argumentTypes[1];
375372
foreach (var method in concreteType.GetMethods())
376373
{
377374
if (!method.IsStatic && method.Name == "Add")
378375
{
379376
var parameters = method.GetParameters();
380-
if (parameters.Length == 2 && parameters[0].ParameterType == typeof(string) && parameters[1].ParameterType == valueType)
377+
if (parameters.Length == 2 && parameters[0].ParameterType == keyType && parameters[1].ParameterType == valueType)
381378
{
382379
addMethod = method;
383380
return true;

0 commit comments

Comments
 (0)