我引用的配置文件是否需要位于项目的主目录中?
Do config files I'm referencing need to be in a project's home directory?
我正在尝试将连接字符串和凭据数据存储在 .config
文件中。我无法将带有 connection/credentials 的配置推送到存储库;配置将位于一个安全的同步文件夹中,该文件夹不是主目录。
我可以将 connection/credentials 存储在主目录的 app.config
文件中,并使用 FSharp.Configuration
库访问它:
type connection = AppSettings<"app.config">
但是如果我尝试访问不同目录中的配置
open System.IO
open FSharp.Configuration
let baseDirectory = __SOURCE_DIRECTORY__
let baseDirectory' = Directory.GetParent(baseDirectory)
let configPath = "Tresor\app.config"
let fullConfigPath = Path.Combine(baseDirectory'.FullName, configPath)
type Settings = AppSettings<fullConfigPath>
fullConfigPath
错误与
This is not a valid constant expression or custom attribute value.
即使我尝试使用 yaml 类型提供程序
let yamlPath = "Tresor\Config.yaml"
let fullYamlPath = Path.Combine(baseDirectory'.FullName, yamlPath)
type Config = YamlConfig<FilePath = fullYamlPath>
我在 fullYamlPath
.
中遇到了类似的错误
为什么我无法访问主目录之外的文件?我是否正确构建了文件路径?
简短回答:抱歉,您 可能 搞砸了,尽管有一个使用 SelectExecutableFile
的解决方法 可能适合你。
长答案:
这不是类型提供者的工作方式。
当您使用类型提供程序为您提供类型时,类型的提供发生在编译时(否则,有什么意义?)。这意味着类型提供者接受的所有输入 also 需要在编译时知道。但是在您的代码中,fullConfigPath
或 fullYamlPath
的值在执行 Path.Combine
之前是未知的,这只会在运行时发生。
它应该的工作方式是,类型提供程序会获取一些"template"文件(或数据库,或URL,或任何它需要的东西),它可以分析并根据其内容为您生成类型。然后,稍后,在运行时,您将指定从何处获取实际 data。
重申一下,这一切发生在两个阶段:
- 编译时的数据形状(又名 "structure" 又名 "schema")。
- 运行时的实际数据。
这是数据库提供商通常的工作方式:
// Pseudocode. I don't have actual libraries handy.
type Db = SqlProvider<"Server=localhost;Database=my_development_db;Integrated Security=true">
let dbConnection = Db.OpenConnection Config.ProductionConnectionString
理论上,AppSettings
和 YamlConfig
提供商的工作方式有些相似:
type Config = AppSettings<"app.config">
let config = Config.OpenConfigFile "MyProgram.exe.config"
let someSetting = config.SomeSetting;
不幸的是,情况并非如此(出于某种原因)。
YamlConfig
提供程序无法加载备用配置文件(它将始终查找在编译时指定的配置文件)。但是 AppSettings
供应商确实给你 some control via the SelectExecutableFile
method. This is a static method that you can call in order to select the source of the data once and for all. And it doesn't take the config file path either, but only the exe
file path, which it then passes to ConfigurationManager.OpenExeConfiguration
:
type Config = AppSettings<"app.config">
Config.SelectExecutableFile "MyProgram.exe"
let someSetting = Config.SomeSetting;
这让我不确定它如何与网络应用程序一起使用。
我想这可以提供一个 解决方法:调用 SelectExecutableFile
并传入没有 .config
扩展名的配置文件的路径,这应该可以工作.但是您还需要创建一个同名的虚拟文件,但没有 .config
扩展名(它将代表 exe
文件),因为库 checks for its presence.
底线是,没有支持你想做的事情,很遗憾,我建议你file an issue。
我正在尝试将连接字符串和凭据数据存储在 .config
文件中。我无法将带有 connection/credentials 的配置推送到存储库;配置将位于一个安全的同步文件夹中,该文件夹不是主目录。
我可以将 connection/credentials 存储在主目录的 app.config
文件中,并使用 FSharp.Configuration
库访问它:
type connection = AppSettings<"app.config">
但是如果我尝试访问不同目录中的配置
open System.IO
open FSharp.Configuration
let baseDirectory = __SOURCE_DIRECTORY__
let baseDirectory' = Directory.GetParent(baseDirectory)
let configPath = "Tresor\app.config"
let fullConfigPath = Path.Combine(baseDirectory'.FullName, configPath)
type Settings = AppSettings<fullConfigPath>
fullConfigPath
错误与
This is not a valid constant expression or custom attribute value.
即使我尝试使用 yaml 类型提供程序
let yamlPath = "Tresor\Config.yaml"
let fullYamlPath = Path.Combine(baseDirectory'.FullName, yamlPath)
type Config = YamlConfig<FilePath = fullYamlPath>
我在 fullYamlPath
.
为什么我无法访问主目录之外的文件?我是否正确构建了文件路径?
简短回答:抱歉,您 可能 搞砸了,尽管有一个使用 SelectExecutableFile
的解决方法 可能适合你。
长答案:
这不是类型提供者的工作方式。
当您使用类型提供程序为您提供类型时,类型的提供发生在编译时(否则,有什么意义?)。这意味着类型提供者接受的所有输入 also 需要在编译时知道。但是在您的代码中,fullConfigPath
或 fullYamlPath
的值在执行 Path.Combine
之前是未知的,这只会在运行时发生。
它应该的工作方式是,类型提供程序会获取一些"template"文件(或数据库,或URL,或任何它需要的东西),它可以分析并根据其内容为您生成类型。然后,稍后,在运行时,您将指定从何处获取实际 data。
重申一下,这一切发生在两个阶段:
- 编译时的数据形状(又名 "structure" 又名 "schema")。
- 运行时的实际数据。
这是数据库提供商通常的工作方式:
// Pseudocode. I don't have actual libraries handy.
type Db = SqlProvider<"Server=localhost;Database=my_development_db;Integrated Security=true">
let dbConnection = Db.OpenConnection Config.ProductionConnectionString
理论上,AppSettings
和 YamlConfig
提供商的工作方式有些相似:
type Config = AppSettings<"app.config">
let config = Config.OpenConfigFile "MyProgram.exe.config"
let someSetting = config.SomeSetting;
不幸的是,情况并非如此(出于某种原因)。
YamlConfig
提供程序无法加载备用配置文件(它将始终查找在编译时指定的配置文件)。但是 AppSettings
供应商确实给你 some control via the SelectExecutableFile
method. This is a static method that you can call in order to select the source of the data once and for all. And it doesn't take the config file path either, but only the exe
file path, which it then passes to ConfigurationManager.OpenExeConfiguration
:
type Config = AppSettings<"app.config">
Config.SelectExecutableFile "MyProgram.exe"
let someSetting = Config.SomeSetting;
这让我不确定它如何与网络应用程序一起使用。
我想这可以提供一个 解决方法:调用 SelectExecutableFile
并传入没有 .config
扩展名的配置文件的路径,这应该可以工作.但是您还需要创建一个同名的虚拟文件,但没有 .config
扩展名(它将代表 exe
文件),因为库 checks for its presence.
底线是,没有支持你想做的事情,很遗憾,我建议你file an issue。