foreach (TypeSpec type in types)
{
- TypeSpecKind kind = type.SpecKind;
+ TypeSpec effectiveType = type.EffectiveType;
+ TypeSpecKind kind = effectiveType.SpecKind;
EmitStartBlock($"if (type == typeof({type.MinimalDisplayString}))");
- if (type is ParsableFromStringSpec stringParsableType)
+ if (effectiveType is ParsableFromStringSpec stringParsableType)
{
EmitCastToIConfigurationSection();
EmitBindLogicFromString(
checkForNullSectionValue: stringParsableType.StringParsableTypeKind is not StringParsableTypeKind.AssignFromSectionValue,
useIncrementalStringValueIdentifier: false);
}
- else if (!EmitInitException(type))
+ else if (!EmitInitException(effectiveType))
{
- EmitBindCoreCall(type, Identifier.obj, Identifier.configuration, InitializationKind.Declaration);
+ EmitBindCoreCall(effectiveType, Identifier.obj, Identifier.configuration, InitializationKind.Declaration);
_writer.WriteLine($"return {Identifier.obj};");
}
}
[Fact]
- public void GetScalar()
+ public void Get_Scalar()
{
var dic = new Dictionary<string, string>
{
}
[Fact]
- public void GetScalarNullable()
+ public void Get_ScalarNullable()
{
var dic = new Dictionary<string, string>
{
}
[Fact]
+ public void GetValue_Scalar()
+ {
+ var dic = new Dictionary<string, string>
+ {
+ {"Integer", "-2"},
+ {"Boolean", "TRUe"},
+ {"Nested:Integer", "11"}
+ };
+ var configurationBuilder = new ConfigurationBuilder();
+ configurationBuilder.AddInMemoryCollection(dic);
+ var config = configurationBuilder.Build();
+
+ Assert.True(config.GetSection("Boolean").Get<bool>());
+ Assert.Equal(-2, config.GetSection("Integer").Get<int>());
+ Assert.Equal(11, config.GetSection("Nested:Integer").Get<int>());
+
+ Assert.True((bool)config.GetSection("Boolean").Get(typeof(bool)));
+ Assert.Equal(-2, (int)config.GetSection("Integer").Get(typeof(int)));
+ Assert.Equal(11, (int)config.GetSection("Nested:Integer").Get(typeof(int)));
+ }
+
+ [Fact]
+ public void GetValue_ScalarNullable()
+ {
+ var dic = new Dictionary<string, string>
+ {
+ {"Integer", "-2"},
+ {"Boolean", "TRUe"},
+ {"Nested:Integer", "11"}
+ };
+ var configurationBuilder = new ConfigurationBuilder();
+ configurationBuilder.AddInMemoryCollection(dic);
+ var config = configurationBuilder.Build();
+
+ Assert.True(config.GetSection("Boolean").Get<bool?>());
+ Assert.Equal(-2, config.GetSection("Integer").Get<int?>());
+ Assert.Equal(11, config.GetSection("Nested:Integer").Get<int?>());
+
+ Assert.True(config.GetSection("Boolean").Get(typeof(bool?)) is true);
+ Assert.Equal(-2, (int)config.GetSection("Integer").Get(typeof(int?)));
+ Assert.Equal(11, (int)config.GetSection("Nested:Integer").Get(typeof(int?)));
+ }
+
+ [Fact]
public void CanBindToObjectProperty()
{
var dic = new Dictionary<string, string>
[Fact]
public void CanBindRecordStructOptions()
{
- var dic = new Dictionary<string, string>
+ IConfiguration config = GetConfiguration("Length", "Color");
+ Validate(config.Get<RecordStructTypeOptions>());
+ Validate(config.Get<RecordStructTypeOptions?>().Value);
+
+ config = GetConfiguration("Options.Length", "Options.Color");
+ // GetValue works for only primitives.
+ //Reflection impl handles them by honoring `TypeConverter` only.
+ // Source-gen supports based on an allow-list.
+ Assert.Equal(default(RecordStructTypeOptions), config.GetValue<RecordStructTypeOptions>("Options"));
+ Assert.False(config.GetValue<RecordStructTypeOptions?>("Options").HasValue);
+
+ static void Validate(RecordStructTypeOptions options)
{
- {"Length", "42"},
- {"Color", "Green"},
- };
- var configurationBuilder = new ConfigurationBuilder();
- configurationBuilder.AddInMemoryCollection(dic);
- var config = configurationBuilder.Build();
+ Assert.Equal(42, options.Length);
+ Assert.Equal("Green", options.Color);
+ }
- var options = config.Get<RecordStructTypeOptions>();
- Assert.Equal(42, options.Length);
- Assert.Equal("Green", options.Color);
+ static IConfiguration GetConfiguration(string key1, string key2)
+ {
+ var dic = new Dictionary<string, string>
+ {
+ { key1, "42" },
+ { key2, "Green" },
+ };
+
+ var configurationBuilder = new ConfigurationBuilder();
+ configurationBuilder.AddInMemoryCollection(dic);
+ return configurationBuilder.Build();
+ }
}
[Fact]