我刚刚开始使用 C# 9 和 .NET 5.0,特别是新record结构。我发现我有很多关于记录类型速记语法的优秀用例。
我考虑过的用例之一是对 ASP.NET Core 应用程序使用recorddto in IOptions<>,而不是常规类。这些选项类通常很简单,所以我认为它非常适合,但似乎我不能让它轻松工作,因为使用配置应用程序IOptions<>需要对象具有无参数构造函数。
public record MyOptions(string OptionA, int OptionB);
public class Startup
{
public void ConfigureServices(IServiceCollection services) {
services.Configure<MyOptions>(Configuration.GetSection(nameof(MyOptions)));
}
...
}
public class MyController : Controller
{
private readonly MyOptions _options;
public MyController(IOptions<MyOptions> options) {
_options = options.Value; // This throws an exception at runtime
}
}
Run Code Online (Sandbox Code Playgroud)
上面的示例在尝试访问该IOption<>.Value属性时抛出以下异常:
System.MissingMethodException: '没有为类型 'AcmeSolution.MyOptions' 定义无参数构造函数。
有没有办法配置IOptions配置系统以使用记录的构造函数反序列化选项,而不是需要无参数的构造函数?
我可以对记录使用普通语法,但是使用类确实没有任何好处。
Bra*_*ano 15
C#10
我知道这个问题专门引用了 C# 9,但如果您生活在当下(我怀疑你们大多数人都是这样),那么这在 C# 10 (ASP.NET Core 6) 中可以按预期工作:
public record MyOptions
{
public string MyProperty { get; init; }
}
// ...
builder.Services.Configure<MyOptions>(builder.Configuration);
Run Code Online (Sandbox Code Playgroud)
Bli*_*ndy 11
有没有办法配置 IOptions 配置系统以使用记录的构造函数反序列化选项,而不是需要无参数构造函数?
不,通常 ASP.Net Core 使用大量运行时类型实例化,这需要事先知道的构造函数调用,在这种情况下,它需要一个没有参数的构造函数。
但是,您可以使您的记录类具有无参数构造函数:
public record MyOptions(string OptionA, int OptionB)
{
public MyOptions(): this(default, default) {}
}
Run Code Online (Sandbox Code Playgroud)
这值得么?诶。由你决定。在性能方面,它并不比普通课程差,所以选择任何你觉得更清晰的课程!
编辑:或者,您应该可以使用此表单:
public record MyOptions(string OptionA = default, int OptionB = default);
Run Code Online (Sandbox Code Playgroud)