Skip to content

ConfigurationBinding source generator ignores init-only properties without warning #107856

Open
@RichardD2

Description

@RichardD2

Description

I am trying to migration some (working) configuration code to use the new configuration source binding generator. However, the source generator never initializes the properties of the configuration object, and no warning or error is generated to highlight the issue.

Reproduction Steps

Configuration section:

public class SqlServerSettings
{
    public int? CompatibilityLevel { get; init; }
}

Usage:

private static int? GetCompatibilityLevel(IConfiguration configuration)
{
    return configuration.GetSection("SqlServer").Get<SqlServerSettings>()?.CompatibilityLevel;
}

appSettings.json:

{
    "SqlServer": {
        "CompatibilityLevel": 130
    }
}

Expected behavior

Ideally, GetCompatibilityLevel should return 130 (probably impossible).

Alternatively, a compiler warning / error should be issued to highlight the fact that the source generator cannot set init-only properties.

Actual behavior

GetCompatibilityLevel returns 0.

The generated BindCore method does not attempt to set any properties:

public static void BindCore(IConfiguration configuration, ref SqlServerSettings instance, bool defaultValueIfNotFound, BinderOptions? binderOptions)
{
    ValidateConfigurationKeys(typeof(SqlServerSettings), s_configKeys_SqlServerSettings, configuration, binderOptions);
}

No errors or warnings are issued.

Regression?

No response

Known Workarounds

Changing the init-only property to a writeable property restores the correct behaviour.

public class SqlServerSettings
{
    public int? CompatibilityLevel { get; set; }
}
public static void BindCore(IConfiguration configuration, ref SqlServerSettings instance, bool defaultValueIfNotFound, BinderOptions? binderOptions)
{
    ValidateConfigurationKeys(typeof(SqlServerSettings), s_configKeys_SqlServerSettings, configuration, binderOptions);

    if (configuration["CompatibilityLevel"] is string value2)
    {
        instance.CompatibilityLevel = ParseInt(value2, () => configuration.GetSection("CompatibilityLevel").Path);
    }
}

Configuration

.NET SDK:
Version: 8.0.400
Commit: 36fe6dda56
Workload version: 8.0.400-manifests.6c274a57
MSBuild version: 17.11.3+0c8610977

Runtime Environment:
OS Name: Windows
OS Version: 10.0.22631
OS Platform: Windows
RID: win-x64
Base Path: C:\Program Files\dotnet\sdk\8.0.400\

Visual Studio 2022 v17.11.3

Other information

Possibly related to #92638?

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions