我引用的配置文件是否需要在项目的主目录中? [英] Do config files I'm referencing need to be in a project's home directory?

查看:99
本文介绍了我引用的配置文件是否需要在项目的主目录中?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



我可以将连接/凭据存储在<主目录中的code> app.config 文件,并使用 FSharp.Configuration 库进行访问:

 类型连接= AppSettings< app.config> 

但是如果我尝试访问其他目录中的配置

 打开System.IO 
打开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 错误

 这不是有效的常量表达式或自定义属性值。 

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

  let yamlPath = Tresor\Config.yaml 
let fullYamlPath = Path.Combine(baseDirectory'.FullName,yamlPath)
type Config = YamlConfig< ; FilePath = fullYamlPath>

我对于 fullYamlPath 遇到类似的错误



我是否有原因无法访问主目录之外的文件?我是在正确构建文件路径吗?

解决方案

简短答案::抱歉,您是可能是搞砸了,尽管有一种解决方法是使用 SelectExecutableFile 可能为您工作。



长答案:

这不是类型提供程序的工作方式。



使用类型提供程序为您提供类型时,在编译时会提供类型(否则,意义何在?)。这意味着在编译时需要知道类型提供程序还接受 的所有输入。但是在您的代码中,直到 Path才知道 fullConfigPath fullYamlPath 的值。合并被执行,这只会在运行时发生。



应该的工作方式是提供者将获取一些模板文件(或数据库,URL或其他内容),该文件可以分析其内容并为您生成类型。然后,稍后,在运行时,您将指定从何处获取实际的数据



要重申,这全部分两个阶段进行:


  1. 在编译时的数据形状(即结构或 schema)。

  2. 运行时的实际数据。

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

  //伪代码。我没有实际的图书馆。 
类型Db = SqlProvider< Server = localhost; Database = my_development_db; Integrated Security = true>

让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 提供程序确实为您提供了通过 SelectExecutableFile 方法 some 控件。这是一个静态方法,您可以调用该方法来一次选择数据源。而且它也不使用配置文件路径,而仅使用 exe 文件路径,然后将其传递给 ConfigurationManager.OpenExeConfiguration

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

让someSetting = Config.SomeSetting;

这让我不确定它如何与Web应用程序一起使用。



我想这可以提供解决方法:调用 SelectExecutableFile ,并在 .config 扩展名,应该可以。但是,您还需要创建一个具有相同名称的虚拟文件,但没有 .config 扩展名(它将代表 exe 文件),因为该库检查它的存在



最重要的是,您尝试执行的操作不支持,这很可惜,我建议您提出问题。 p>

I'm trying to store connection string and credentials data in a .config file. I can't push the config with the connection/credentials to a repo; the config will be in a secure, synced folder that isn't the home directory.

I can store the connection/credentials in the app.config file in the home directory and access it with the FSharp.Configuration library:

type connection = AppSettings<"app.config">

but if I try to access a config in a different directory

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>

the fullConfigPath errors out with

This is not a valid constant expression or custom attribute value.

Even if I try to use the yaml type provider

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

I get a similar error for the fullYamlPath.

Is there a reason I can't access files outside of the home directory? Am I constructing the file path correctly?

解决方案

Short answer: sorry, you're probably screwed, although there is a workaround using SelectExecutableFile that might work for you.

Long answer:
This is not how type providers work.

When you use a type provider to provide a type for you, the providing of the type happens at compile time (otherwise, what would be the point?). This means that all inputs that the type provider takes also need to be known at compile time. But in your code, the value of fullConfigPath or fullYamlPath isn't known until Path.Combine is executed, which will only happen at runtime.

The way it's supposed to work is, the type provider would take some "template" file (or database, or URL, or whatever it takes), which it can analyze and generate you the type from its contents. And then, later, at runtime, you would specify where to get the actual data from.

To reiterate, this all happens in two stages:

  1. Data shape (aka "structure" aka "schema") at compile time.
  2. Actual data at runtime.

This is how database providers usually work:

// 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

Theoretically, both AppSettings and YamlConfig providers would work somewhat similar:

type Config = AppSettings<"app.config">
let config = Config.OpenConfigFile "MyProgram.exe.config"
let someSetting = config.SomeSetting;

Unfortunately, this is not the case (for some reason).

YamlConfig provider doesn't have any way to load an alternate config file (it will always look for the one specified at compile time). But the AppSettings provider does give you 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;

Which makes me unsure of how it would work with a web app.

I suppose this could give a workaround: call SelectExecutableFile and pass in the path to your config file sans the .config extension, that should work. But you also need to create a dummy file with the same name, but without the .config extension (which would stand in for the exe file), because the library checks for its presence.

The bottom line is, there is no support for what you're trying to do, and it's a shame, and I suggest you file an issue about it.

这篇关于我引用的配置文件是否需要在项目的主目录中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆