Long story short I can extract the appsettings.json
to the Configuration
type when I use C#-like classes:
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
But when using F# record types:
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
I end up with configuration that is no different than the value I gave before calling the 'Bind' method (even though I did'nt any exception), basically it's like nothing happened.
Note: I have the same behaviour when I use the defaults below:
let configuration = {
RabbitMQ = Unchecked.defaultof<Connection>
PostgreSQL = Unchecked.defaultof<Connection>
}
Configuration
to your own setting type is a bad idea and can only confuse people that try to read your code. In any case, F# records are immutable. You can't change their properties once you create them. You don't need to useBind
in any case, you can useGet<T>
to retrieve a strongly typed settings class. – ReamConfiguration
was purposfully chosen for this SO post not in actual production code. F# records are immutable but depending on the serializer can leverage the constructor created behind the scene (in Marten it seems to work at least).Get<T>
only shows that the deserializer is looking for a parameterless constructor. However that works when settings[<CLIMutable>]
attribute on the record types. – CephalizationConfiguration
was a random class.Configuration
is the common name given to theIConfiguration
variable used in the Startup configuration methods. – Ream