我正在引用的配置文件是否需要位于项目的主目录中?

Ste*_*ven 2 f# config

我正在尝试将连接字符串和凭据数据存储在.config文件中.我无法使用连接/凭证将配置推送到repo; 配置将位于安全的同步文件夹中,该文件夹不是主目录.

我可以将连接/凭证存储app.config在主目录中的文件中,并使用FSharp.Configuration库访问它:

type connection = AppSettings<"app.config">
Run Code Online (Sandbox Code Playgroud)

但是,如果我尝试访问不同目录中的配置

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>
Run Code Online (Sandbox Code Playgroud)

fullConfigPath错误不与

This is not a valid constant expression or custom attribute value.
Run Code Online (Sandbox Code Playgroud)

即使我尝试使用yaml类型提供程序

let yamlPath = "Tresor\Config.yaml"
let fullYamlPath = Path.Combine(baseDirectory'.FullName, yamlPath)
type Config = YamlConfig<FilePath = fullYamlPath>
Run Code Online (Sandbox Code Playgroud)

我得到了类似的错误fullYamlPath.

有没有理由我无法访问主目录之外的文件?我正确构建文件路径吗?

Fyo*_*kin 5

简短的回答:对不起,你可能搞砸,虽然有使用一种解决方法SelectExecutableFile可能为你工作.

答案
长:这不是类型提供者的工作方式.

当您使用类型提供程序为您提供类型时,类型的提供发生在编译时(否则,重点是什么?).这意味着类型提供程序所需的所有输入需要在编译时知道.但是在你的代码中,只有在执行时才会知道fullConfigPath或者fullYamlPath不知道Path.Combine它的值,这只会在运行时发生.

应该工作的方式是,类型提供程序将采用一些"模板"文件(或数据库,或URL,或任何它需要),它可以分析并从其内容生成您的类型.然后,在运行时,您将指定从何处获取实际数据.

重申一下,这一切都分两个阶段进行:

  1. 编译时的数据形状(又名"结构"又名"模式").
  2. 运行时的实际数据.

这是数据库提供者通常的工作方式:

// 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
Run Code Online (Sandbox Code Playgroud)

从理论上讲,两者AppSettingsYamlConfig提供者的工作方式有些相似:

type Config = AppSettings<"app.config">
let config = Config.OpenConfigFile "MyProgram.exe.config"
let someSetting = config.SomeSetting;
Run Code Online (Sandbox Code Playgroud)

不幸的是,情况并非如此(出于某种原因).

YamlConfigprovider没有任何方法可以加载备用配置文件(它始终会查找在编译时指定的配置文件).但是AppSettings提供商确实通过这种方法给你一些控制权SelectExecutableFile.这是一种静态方法,您可以调用该方法以便一劳永逸地选择数据源.并且它不会接受配置文件路径,而只接受exe文件路径,然后传递给ConfigurationManager.OpenExeConfiguration它:

type Config = AppSettings<"app.config">
Config.SelectExecutableFile "MyProgram.exe"

let someSetting = Config.SomeSetting;
Run Code Online (Sandbox Code Playgroud)

这使我不确定如何使用Web应用程序.

我想这可以给出一个解决方法:调用SelectExecutableFile并传入配置文件的路径.config,但是应该可以使用扩展.但是你还需要创建一个具有相同名称的虚拟文件,但没有.config扩展名(代表exe文件),因为库会检查它的存在.

最重要的是,你没有支持你想做什么,这是一个耻辱,我建议你提出一个问题.