Skip to content

Binding NpgsqlConnectionStringBuilder to configuration does not work on .net 7.0 #78908

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

Closed
frabe1579 opened this issue Nov 28, 2022 · 3 comments

Comments

@frabe1579
Copy link

Description

I'm used to bind an instance of NpgsqlConnectionStringBuilder (from Npgsql) to the configuration during startup, but this does not work anymore after upgrading to .net 7.0: The instance remains empty and values are not loaded from configuration

Reproduction Steps

  • Create a Console Project like this:
<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net7.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.Extensions.Configuration" Version="7.0.0" />
    <PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="7.0.0" />
    <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="7.0.0" />
    <PackageReference Include="Npgsql" Version="7.0.0" />
  </ItemGroup>

  <ItemGroup>
    <None Update="appsettings.json">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </None>
  </ItemGroup>

</Project>
  • Add this to Program.cs:
using System.Diagnostics;
using Microsoft.Extensions.Configuration;
using Npgsql;

var configuration = new ConfigurationBuilder()
  .AddJsonFile("appsettings.json")
  .Build();

Debug.Assert(configuration["db:host"] == "localhost");

var csb = new NpgsqlConnectionStringBuilder();
configuration.GetSection("db").Bind(csb);
var cs = csb.ToString();

Debug.Assert(csb.Host != null);
Console.WriteLine("Host is: " + csb.Host);

Add appsettings.json file with this content:

{
  "db": {
    "host": "localhost"
  }
}

If you dotnet run, the program crashes due to the last assertion: the values are not loaded from configuration.
If the project is downgraded to .net6.0 (and also the deps), the program runs ok, the values are correctly loaded.
I think it's not a direct problem of Npgsql, but something related to a change in .net7 that is not compatible with internal mappings used by NpgsqlConnectionStringBuilder.
A direct binding to a POCO runs like a charm, but with NpgsqlConnectionStringBuilder no.

Expected behavior

The configuration data is loaded and mapped to the instance passed to Bind.

Actual behavior

The configuration data is not loaded and the instance passed to Bind reamins empty.

Regression?

Yes, this worked on .net 6.0, at least up to 6.0.10.

Known Workarounds

No direct workaraoud, it's necessary to use a POCO to bind from configuration.

Configuration

.NET 7.0
Window 11 Pro x64

Other information

The problem might be in changes to configuration binder, considering that NpgsqlConnectionStringBuilder exposes properties but also a IDictionary<string, object?>.

@ghost ghost added area-Extensions-Configuration untriaged New issue has not been triaged by the area owner labels Nov 28, 2022
@ghost
Copy link

ghost commented Nov 28, 2022

Tagging subscribers to this area: @dotnet/area-extensions-configuration
See info in area-owners.md if you want to be subscribed.

Issue Details

Description

I'm used to bind an instance of NpgsqlConnectionStringBuilder (from Npgsql) to the configuration during startup, but this does not work anymore after upgrading to .net 7.0: The instance remains empty and values are not loaded from configuration

Reproduction Steps

  • Create a Console Project like this:
<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net7.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.Extensions.Configuration" Version="7.0.0" />
    <PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="7.0.0" />
    <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="7.0.0" />
    <PackageReference Include="Npgsql" Version="7.0.0" />
  </ItemGroup>

  <ItemGroup>
    <None Update="appsettings.json">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </None>
  </ItemGroup>

</Project>
  • Add this to Program.cs:
using System.Diagnostics;
using Microsoft.Extensions.Configuration;
using Npgsql;

var configuration = new ConfigurationBuilder()
  .AddJsonFile("appsettings.json")
  .Build();

Debug.Assert(configuration["db:host"] == "localhost");

var csb = new NpgsqlConnectionStringBuilder();
configuration.GetSection("db").Bind(csb);
var cs = csb.ToString();

Debug.Assert(csb.Host != null);
Console.WriteLine("Host is: " + csb.Host);

Add appsettings.json file with this content:

{
  "db": {
    "host": "localhost"
  }
}

If you dotnet run, the program crashes due to the last assertion: the values are not loaded from configuration.
If the project is downgraded to .net6.0 (and also the deps), the program runs ok, the values are correctly loaded.
I think it's not a direct problem of Npgsql, but something related to a change in .net7 that is not compatible with internal mappings used by NpgsqlConnectionStringBuilder.
A direct binding to a POCO runs like a charm, but with NpgsqlConnectionStringBuilder no.

Expected behavior

The configuration data is loaded and mapped to the instance passed to Bind.

Actual behavior

The configuration data is not loaded and the instance passed to Bind reamins empty.

Regression?

Yes, this worked on .net 6.0, at least up to 6.0.10.

Known Workarounds

No direct workaraoud, it's necessary to use a POCO to bind from configuration.

Configuration

.NET 7.0
Window 11 Pro x64

Other information

The problem might be in changes to configuration binder, considering that NpgsqlConnectionStringBuilder exposes properties but also a IDictionary<string, object?>.

Author: frabe1579
Assignees: -
Labels:

untriaged, area-Extensions-Configuration

Milestone: -

@tarekgh
Copy link
Member

tarekgh commented Nov 28, 2022

This is fixed and should be released in the next service release of .NET 7.0.

#78118

If you are interested to try the fix from now, you may add the following nuget feed

    <add key="dotnet8" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet8/nuget/v3/index.json" />

and the use package version like 8.0.0-alpha.1.22578.1.

@tarekgh tarekgh closed this as completed Nov 28, 2022
@ghost ghost removed the untriaged New issue has not been triaged by the area owner label Nov 28, 2022
@frabe1579
Copy link
Author

I can confirm, with 8.0.0-alpha.1.22578.1 the problem is solved.

@ghost ghost locked as resolved and limited conversation to collaborators Dec 29, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

2 participants