[英]App.config and F# Interactive not working
當我完善我的小寵物項目時,我試圖將所有常量字符串存儲在我的 app.config 文件(鍵、XpathExpressions 等)中。 當我運行編譯的 exe 時,這很好用。 在交互式外殼中,情況並非如此。
我試圖將 .config 文件從我的 bin/Release 目錄復制到 obj/Debug & obj/Release 目錄,但是對ConfigurationManager.AppSettings.Item("key")
的調用總是返回 null。
任何建議如何解決這個問題?
最誠摯的問候
F# Interactive可以處理依賴於app.config
文件的可執行文件。
這樣做的方法是在您的項目中有一個.fs
文件,該文件以COMPILED
定義為條件加載您的.config
:
let GetMyConfig() =
let config =
#if COMPILED
ConfigurationManager.GetSection("MyConfig") :?> MyConfig
#else
let path = __SOURCE_DIRECTORY__ + "/app.config"
let fileMap = ConfigurationFileMap(path)
let config = ConfigurationManager.OpenMappedMachineConfiguration(fileMap)
config.GetSection("MyConfig") :?> MyConfig
#endif
然后在你的腳本文件引用的可執行文件和#load
的.fs
文件,以便:
#I "../Build/Path
#r "ConfiguredApp.exe"
#load "MyConfig.fs"
執行這三行時,您將在 FSI 窗口中看到類似於以下內容的消息:
[Loading C:\\Svn\\trunk\\Source\\ConfiguredApp\\MyConfig.fs]
Binding session to 'C:\\Svn\\Qar\\trunk\\Build\\Path\\ConfiguredApp.exe'...
請注意,您實際上是在 FSI 中引用app.config
(而不是生成的.exe.config
。)
祝你好運...
雖然 FSI 會為您的輸入動態生成代碼,但使用 fsi.exe.config 就可以正常工作。
我創建了這個文件:
<configuration>
<appSettings>
<add key="test" value="bar"/>
</appSettings>
</configuration>
並將其保存為“fsi.exe.config”(程序文件\\fsharp-version\\bin)。
然后啟動 FSI:
> #r "System.configuration";;
--> Referenced 'C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\System.configuration.dll'
> System.Configuration.ConfigurationManager.AppSettings.["test"];;
val it : string = "bar"
它也適用於 Visual Studio。 (但請注意,您需要將會話重置為拾取更改。)
我想我從上面兩個投票最多的答案中提供了兩全其美的答案(特別是對於編寫 fsx 腳本的人):
鑒於此 app.config 文件:
<configuration>
<appSettings>
<add key="foo" value="bar"/>
</appSettings>
</configuration>
以這種方式閱讀foo
:
let appConfigPath = System.IO.Path.Combine(Directory.GetCurrentDirectory(), "app.config")
let fileMap = ExeConfigurationFileMap()
fileMap.ExeConfigFilename <- appConfigPath
let config = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None)
let foo = config.AppSettings.Settings.["foo"].Value
Console.WriteLine(foo)
設置 APP_CONFIG_FILE 可以完成“如果足夠早”的工作。 它似乎無法在 .fsx 文件中盡早完成。 所以它需要重置,根據這篇文章: 在運行時更改默認 app.config
在 F# 中,它看起來像這樣:
open System
open System.Configuration
open System.IO
open System.Reflection
let appConfigPath = System.IO.Path.Combine(Directory.GetCurrentDirectory(), "App.config")
AppDomain.CurrentDomain.SetData("APP_CONFIG_FILE", appConfigPath)
typeof<ConfigurationManager>
.GetField("s_initState", BindingFlags.NonPublic ||| BindingFlags.Static).SetValue(null, 0)
typeof<ConfigurationManager>
.GetField("s_configSystem", BindingFlags.NonPublic ||| BindingFlags.Static).SetValue(null, null)
(typeof<ConfigurationManager>.Assembly.GetTypes()
|> Array.find (fun x -> x.FullName = "System.Configuration.ClientConfigPaths"))
.GetField("s_current", BindingFlags.NonPublic ||| BindingFlags.Static).SetValue(null, null);;
也許您可以使用 ConfigurationManager 上的OpenMappedExeConfiguration 方法手動將 FSI 指向 app.config 文件。
您也可以嘗試在單獨的 AppDomain 中加載程序集 - 您可以將任何文件作為配置文件提供給您使用AppDomainSetup類自己創建的AppDomain 。
事實仍然是 FSI 不太適合這種情況......
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.