【发布时间】:2019-10-19 22:10:50
【问题描述】:
长话短说,当我使用类似 C# 的类时,我可以将 appsettings.json 提取为 Configuration 类型:
type Connection() =
member val Host = Unchecked.defaultof<string> with get,set
member val Port = Unchecked.defaultof<int> with get,set
member val UserName = Unchecked.defaultof<string> with get,set
member val Password = Unchecked.defaultof<string> with get,set
type Configuration() =
member val RabbitMQ = Unchecked.defaultof<Connection> with get,set
member val PostgreSQL = Unchecked.defaultof<Connection> with get,set
let fetchConfiguration =
let builder = (new ConfigurationBuilder())
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", true, true)
.AddEnvironmentVariables();
let configurationRoot = builder.Build();
let configuration = new Configuration()
configurationRoot.Bind(configuration)
configuration
但是当使用 F# 记录类型时:
type Connection = {
Host: string
Port: int32
Username: string
Password: string
}
type Configuration = {
RabbitMQ: Connection
PostgreSQL: Connection
}
let fetchConfiguration =
let builder = (new ConfigurationBuilder())
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", true, true)
.AddEnvironmentVariables();
let configurationRoot = builder.Build();
let configuration = {
RabbitMQ = {
Host = Unchecked.defaultof<string>
Port = Unchecked.defaultof<int>
Username = Unchecked.defaultof<string>
Password = Unchecked.defaultof<string>
}
PostgreSQL = {
Host = Unchecked.defaultof<string>
Port = Unchecked.defaultof<int>
Username = Unchecked.defaultof<string>
Password = Unchecked.defaultof<string>
}
}
configurationRoot.Bind(configuration)
configuration
我最终得到的配置与我在调用“绑定”方法之前给出的值没有什么不同(即使我没有任何异常),基本上就像什么都没发生一样。
注意:当我使用以下默认值时,我的行为相同:
let configuration = {
RabbitMQ = Unchecked.defaultof<Connection>
PostgreSQL = Unchecked.defaultof<Connection>
}
【问题讨论】:
-
将类型名称
Configuration用于您自己的设置类型是一个坏主意,并且只会使试图阅读您的代码的人感到困惑。在任何情况下,F# 记录都是不可变的。创建它们后,您将无法更改它们的属性。在任何情况下您都不需要使用Bind,您可以使用Get<T>来检索强类型设置类。 -
连接和配置记录上的 [
] 属性可能会有所帮助。这告诉编译器在成员实现上添加属性设置器,以便执行反序列化等操作的库可以单独设置成员。 -
@Panagiotis Kanavos
Configuration被故意选择用于此 SO 帖子,而不是在实际生产代码中。 F# 记录是不可变的,但取决于序列化程序,可以利用幕后创建的构造函数(至少在 Marten 中它似乎可以工作)。Get<T>仅表明反序列化器正在寻找无参数构造函数。但是,当在记录类型上设置[<CLIMutable>]属性时,它会起作用。 -
@Wallace Kelly 好用!
-
@EhouarnPerret 仍然让我感到困惑,直到我意识到
Configuration是一个随机类。Configuration是在启动配置方法中使用的IConfiguration变量的通用名称。
标签: c# f# default-value appsettings