将 IConfiguration 绑定到 C# 记录类型

问题描述 投票:0回答:4

我想将配置绑定到记录类型。

这是配置类型的定义(没有无参构造函数):

public record AppConfiguration(string ConnectionString);

这是示例

Main
方法:

public static void Main(string[] args)
{
    var configuration = new ConfigurationBuilder().AddJsonFile("appsettings.json").Build();
    AppConfiguration appConfig = new(); // error
    configuration.GetSection("app").Bind(appConfig);
}

如果我将定义转换为:

public record AppConfiguration
{
    public string ConnectionString {get; init;}
}

它按预期工作,但我宁愿使用记录的“单行”定义。 记录适合此用例吗?

c# configuration c#-record-type
4个回答
4
投票

将配置部分绑定到

record
s 的能力已被作为 .NET 团队提出的一个问题,并且 针对 .NET 7+ 实现,因此一旦您升级到该版本,这将正常工作™:

var appConfig = config.GetSection("app").Get<AppConfiguration>();

自 7.0.0 及更高版本起,它也已添加到

Microsoft.Extensions.Configuration.Binder
NuGet 包中。

或者,您可以使用 Paul Hiles 的 NuGet 包(他的答案中的链接)。


3
投票

第一种方法的问题在于,通过单行声明,您已经自动定义了主构造函数,其中

导致隐式声明的默认类构造函数(如果存在), 被压制。

在第二种情况下,主构造函数是无参数构造函数,因此它按预期工作。为了消除任何疑问,

init
访问器是向后兼容的,因此即使
ConnectionString
没有直接初始化,它也会采用值
null
。我猜,
Bind
方法将使用反射正确填充它。


2
投票

我创建了一个微小的 NuGet 包来处理将配置绑定到位置记录或没有无参数构造函数的类。

如果您引用该包,那么您只需要一行:

configuration.Bind<AppConfiguration>();

如果您的配置文件部分与类型名称不匹配,那么您可以传递部分名称:

configuration.Bind<AppConfiguration>("app");

0
投票

我刚刚遇到这个问题。自从您发布问题以来,此功能似乎已通过 nuget 包引用添加到 Microsoft.Extensions.Configuration.Binder。添加此 nuget 包后,您就可以在配置部分使用 Get() :

 var appConfig = config.GetSection("app").Get<AppConfiguration>();
© www.soinside.com 2019 - 2024. All rights reserved.