2009-03-14 9 views
15

Podczas polerowania mojego małego projektu, próbuję przechowywać wszystkie stałe ciągi w moim pliku app.config (Keys, XpathExpressions itp.). Po uruchomieniu skompilowanego exe działa to świetnie. W przypadku Interactive Shell tak nie jest.App.config i F # Interactive nie działa

Próbowałem skopiować plik .config z katalogu bin/Release do katalogu obj/Debug & obj/Release, ale wywołanie do ConfigurationManager.AppSettings.Item("key") zawsze zwraca wartość null.

Wszelkie sugestie, jak to naprawić?

Z poważaniem

Odpowiedz

0

Problemem jest to, że jest to inny FSI exe działa za kulisami i robi jakieś szalone triki z kompilacji on-the-fly i generowania plików binarnych. Sprawdź, które assembly FSI thinks is running. Możesz być zaskoczony, co znajdziesz :)

będzie rzucać błąd:

System.NotSupportedException: The invoked member is not supported in a dynamic assembly. at System.Reflection.Emit.AssemblyBuilder.get_Location()

Trzeba spojrzeć w jaki sposób dostać się do ustawień app.config zespołów dynamicznych. To może być ból i może nie być tego warte. Jeśli działa jako skompilowany plik binarny, testowałbym te rzeczy, które opierają się na ustawieniach konfiguracji poza FSI.

Powodzenia.

0

Być może można wskazać FSI na plik app.config ręcznie, korzystając z OpenMappedExeConfiguration method w menedżerze konfiguracji ConfigurationManager.

Możesz także spróbować załadować swój zespół w osobnym AppDomain - możesz podać dowolny plik jako plik konfiguracyjny do AppDomain, które sam utworzysz, używając klasy AppDomainSetup.

Th pozostaje faktem, że FSI nie jest dobrze nadaje się do tego rodzaju scenariusz ...

12

Podczas FSI dynamicznie generuje kod dla wejścia, za pomocą fsi.exe.config będzie działać dobrze.

stworzyłem ten plik

<configuration> 
    <appSettings> 
     <add key="test" value="bar"/> 
    </appSettings> 
</configuration> 

i zapisaniu go jako "fsi.exe.config" (program files \ fsharp wersja \ bin).

Następnie rozpoczął 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" 

pracował również z Visual Studio. (Należy jednak pamiętać, że należy zresetować sesję w celu zmiany odbioru).

+0

Ten pracował dla mnie. Chciałem dodać " .. .." dla klienta WCF. Dodałem to do istniejącego "fsi.exe.config", ponownie uruchomiłem FSI, a następnie zadziałał mój "let client = new ServiceClient" :) –

+0

Dla VS 2015, konfiguracje F # znajdują się w 'C: \ Program Files (x86) \ Microsoft SDK \ F # \ 4.0 \ Framework \ v4.0'. –

+0

prawdziwym minusem tego podejścia jest konieczność umieszczenia pliku konfiguracyjnego w tym miejscu (dla skryptów fsx najlepszym rozwiązaniem byłoby, gdyby plik konfiguracyjny mógł znajdować się w tym samym folderze co skrypt, ponieważ jest wymagany w http: // stackoverflow.com/questions/13256167/use-app-config-from-fsx-file) – knocte

13

F # Interaktywna może pracować z plikami wykonywalnymi, które polegają na plikach app.config.

Sposobem na to jest mieć plik .fs w projekcie, który ładuje swoją .config uwarunkowane COMPILED zdefiniować tak:

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 

następnie w odniesieniu pliku skryptu plik wykonywalny i #load plik przeznaczony .fs tak :

#I "../Build/Path

#r "ConfiguredApp.exe"

#load "MyConfig.fs"

Na wykonanie tych trzech linii pojawi się komunikat podobny do następującego w oknie FSI:

[Loading C:\Svn\trunk\Source\ConfiguredApp\MyConfig.fs]

Binding session to 'C:\Svn\Qar\trunk\Build\Path\ConfiguredApp.exe'...

Zauważ, że jesteś rzeczywiście odwołuje się do app.config kiedy w FSI (zamiast wygenerowanego .exe.config.)

Powodzenia ...

0

myślę dostarczyć poniżej najlepsze z obu światów z dwóch najbardziej głosowało odpowiedzi powyżej (szczególnie dla osób piszących skrypty FSX):

Biorąc pod uwagę ten plik app.config:

<configuration> 
    <appSettings> 
     <add key="foo" value="bar"/> 
    </appSettings> 
</configuration> 

Czytaj foo w ten sposób:

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) 
Powiązane problemy