-
Notifications
You must be signed in to change notification settings - Fork 4.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ConfigurationBinder source generator generates code that doesn't compile when using StringValues #94547
Comments
Tagging subscribers to this area: @dotnet/area-extensions-configuration Issue DetailsDescriptionWhen an Options object uses the Reproduction StepsBuild the following app: <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<EnableConfigurationBindingGenerator>true</EnableConfigurationBindingGenerator>
<PublishAot>true</PublishAot>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="9.0.0-dev" />
<PackageReference Include="Microsoft.Extensions.Configuration" Version="9.0.0-dev" />
</ItemGroup>
</Project> using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Primitives;
IConfigurationSection c = new ConfigurationBuilder().Build().GetSection("Options");
c.Get<MyOptions>();
public class MyOptions
{
public IDictionary<string, StringValues> DefaultValues { get; set; } = new Dictionary<string, StringValues>(StringComparer.OrdinalIgnoreCase);
} Expected behaviorThe project should build successfully. Actual behaviorThe build fails with:
The generated code that fails looks like: public static void BindCore(IConfiguration configuration, ref global::Microsoft.Extensions.Primitives.StringValues instance, bool defaultValueIfNotFound, BinderOptions? binderOptions)
{
if (instance is not ICollection<string> temp) // this line has the build error
{
return;
} Regression?No Known WorkaroundsNo response ConfigurationNo response Other informationNo response
|
Definitely the generator shouldn't emit code that doesn't compile. It can do that check at compile time since the struct must be non null and implements ICollection. I wonder if we have an example of someone successfully using a StringValues type with configuration? Actually binding data to it. Maybe it requires collection like data to bind correctly? |
This scenario was found in https://github.com/dotnet/extensions/blob/33abf0c4b36ac8ce5964938b42f06ca31f48d9f6/src/Libraries/Microsoft.AspNetCore.HeaderParsing/HeaderParsingOptions.cs#L16-L24. I tried different combinations of what the config could look like, but I wasn't able to get the reflection based config binder to bind it correctly. I could get a key added to the dictionary, but the StringValues value would always be empty. I looked back in source history, and I don't see any indication that this property was supposed to actually be bound to configuration. All the places that touch it manually add it through code. Tagging some of the people on the original PR to see if they remember if |
This was not intended to be configured from JSON. This kind of configuration option is pretty essential to the behavior of the code, so it's not particularly compelling as a config options controlled from JSON. |
- Enable configuration binder source generator - The only library that can't use the ConfigBinder SG is the HeaderParsing library. - Blocked by dotnet/runtime#94547
* Enable AOT compatibility for all libraries. Fix warnings. - Enable configuration binder source generator - The only library that can't use the ConfigBinder SG is the HeaderParsing library. - Blocked by dotnet/runtime#94547 * Fix Compliance Redaction. * Address PR feedback
* Enable AOT compatibility for all libraries. Fix warnings. - Enable configuration binder source generator - The only library that can't use the ConfigBinder SG is the HeaderParsing library. - Blocked by dotnet/runtime#94547 * Fix Compliance Redaction. * Address PR feedback
* Enable AOT compatibility for all libraries (#4625) * Enable AOT compatibility for all libraries. Fix warnings. - Enable configuration binder source generator - The only library that can't use the ConfigBinder SG is the HeaderParsing library. - Blocked by dotnet/runtime#94547 * Fix Compliance Redaction. * Explicitly reference Microsoft.Extensions.Configuration.Binder For all libraries that use the Configuration.Binder source generator, explicitly reference the NuGet package. This ensures we get the latest version (8.0.1), which has all the source generator fixes. * Respond to PR feedback. - Change ArgumentNullException to normal ArgumentException - Add tests to LoggingRedactionOptions collection setters to keep 100% code coverage. dotnet/runtime#96873 causes these setters to no longer be called in the existing tests.
Confirmed that this is still reproducing in the latest codebase. I'll see about a fix. |
I see we have the same problem for Dictionary too. It's actually very specific to these two cases: Lines 404 to 407 in ae30cba
Lines 471 to 474 in ae30cba
Those are the only two places we identify a type as implementing an interface and need to cast to that interface to bind to it. I think we can fix this by omitting the cast check for a struct. |
In this particular case the reflection based binder will actually treat the type as ICollection and will try to add if data is present:
That doesn't change what we do here, just adding some detail to help understand the scenario. This is a case where a user was never successfully binding to the type, but it was previously a noop and now it's a compile failure when trying to use the generator. One way we could handle this better is to not even introduce the type-specific |
dotnet/runtime#94547 has been fixed in 9.0. We can now use the Configuration Binder in HeaderParsing. This fixes the last AOT warning in the repo. Fix dotnet#4914
dotnet/runtime#94547 has been fixed in 9.0. We can now use the Configuration Binder in HeaderParsing. This fixes the last AOT warning in the repo. Fix #4914
Description
When an Options object uses the
StringValues
type, the ConfigurationBinder Source Generator is generating code that doesn't compile.Reproduction Steps
Build the following app:
Expected behavior
The project should build successfully.
Actual behavior
The build fails with:
The generated code that fails looks like:
Regression?
No
Known Workarounds
No response
Configuration
No response
Other information
No response
The text was updated successfully, but these errors were encountered: