-
Notifications
You must be signed in to change notification settings - Fork 5.2k
Description
Description
Configuration binder populates dictionaries keyed by enums with their default values if they are unset instead of not adding the entry.
Reproduction Steps
TestLibrary.cs
using System.Collections.Generic;
using System.IO;
using Microsoft.Extensions.Configuration;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace TestLibrary
{
public sealed class EntryHolder
{
public int Entry { get; set; }
}
public enum TestEnum
{
Enum1,
Enum2,
}
public sealed class EnumConfig
{
public IDictionary<TestEnum, EntryHolder> EnumHolder { get; set; }
}
[TestClass]
public sealed class TestClass
{
static EnumConfig BuildConfig(string yaml)
{
var tempFile = Path.GetTempFileName();
try
{
File.WriteAllText(tempFile, yaml);
var configuration = new ConfigurationBuilder();
configuration.AddYamlFile(tempFile);
var section = configuration.Build().GetSection("ConfigSection");
var config = new EnumConfig();
section.Bind(config, options => options.ErrorOnUnknownConfiguration = false);
return config;
}
finally
{
File.Delete(tempFile);
}
}
[TestMethod]
public void TestWithoutEntries()
{
var configEntry = BuildConfig(@"
ConfigSection:
EnumHolder:
Enum1:
Enum2:
");
Assert.IsNotNull(configEntry, "EnumConfig was null");
Assert.IsNotNull(configEntry.EnumHolder, "EnumHolder was null");
Assert.AreEqual(0, configEntry.EnumHolder.Count);
}
}
}
TestLibrary.csproj
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net6.0;net7.0;net8.0</TargetFrameworks>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Configuration" Version="8.0.0-preview.6.23329.7" />
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="8.0.0-preview.5.23280.8" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.6.3" />
<PackageReference Include="MSTest.TestAdapter" Version="3.1.1" />
<PackageReference Include="MSTest.TestFramework" Version="3.1.1" />
<PackageReference Include="NetEscapades.Configuration.Yaml" Version="3.1.0" />
</ItemGroup>
</Project>
Expected behavior
The EnumHolder
should be empty and tests should pass.
Actual behavior
The tests fails because the dictionary is filled with null
s keyed by TestEnum
.
Regression?
Yes!
This behavior does not occur if you downgrade to Microsoft.Extensions.Configuration.Binder
version 8.0.0-preview.4.23259.5
.
It is not documented as a breaking change.
Known Workarounds
Have your bound class dictionary property explicitly eliminate default initialized values of the KVPs in this case.
Configuration
The problem was first released in Microsoft.Extensions.Configuration.Binder
v8.0.0-preview.5.23280.8
.
x64 Win 10 Pro 24GB RAM i5-3570K... Is this really necessary?
PS C:\Users\Cyberboss> dotnet --list-sdks
3.1.100 [C:\Program Files\dotnet\sdk]
5.0.214 [C:\Program Files\dotnet\sdk]
6.0.120 [C:\Program Files\dotnet\sdk]
7.0.306 [C:\Program Files\dotnet\sdk]
8.0.100-preview.6.23330.14 [C:\Program Files\dotnet\sdk]
PS C:\Users\Cyberboss> dotnet --version
8.0.100-preview.6.23330.14
Other information
One of these two PRs is to blame if my git detective skills are decent. Probably the first: