我想将配置绑定到记录类型。
这是配置类型的定义(没有无参构造函数):
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;}
}
它按预期工作,但我宁愿使用记录的“单行”定义。 记录适合此用例吗?
将配置部分绑定到
record
s 的能力已被作为 .NET 团队提出的一个问题,并且 针对 .NET 7+ 实现,因此一旦您升级到该版本,这将正常工作™:
var appConfig = config.GetSection("app").Get<AppConfiguration>();
Microsoft.Extensions.Configuration.Binder
NuGet 包中。
或者,您可以使用 Paul Hiles 的 NuGet 包(他的答案中的链接)。
第一种方法的问题在于,通过单行声明,您已经自动定义了主构造函数,其中
导致隐式声明的默认类构造函数(如果存在), 被压制。
在第二种情况下,主构造函数是无参数构造函数,因此它按预期工作。为了消除任何疑问,
init
访问器是向后兼容的,因此即使ConnectionString
没有直接初始化,它也会采用值null
。我猜,Bind
方法将使用反射正确填充它。
我创建了一个微小的 NuGet 包来处理将配置绑定到位置记录或没有无参数构造函数的类。
如果您引用该包,那么您只需要一行:
configuration.Bind<AppConfiguration>();
如果您的配置文件部分与类型名称不匹配,那么您可以传递部分名称:
configuration.Bind<AppConfiguration>("app");
我刚刚遇到这个问题。自从您发布问题以来,此功能似乎已通过 nuget 包引用添加到 Microsoft.Extensions.Configuration.Binder。添加此 nuget 包后,您就可以在配置部分使用 Get() :
var appConfig = config.GetSection("app").Get<AppConfiguration>();