2009-03-14 21 views
15

Como estoy puliendo mi proyecto de mascota, estoy tratando de almacenar todas las cadenas constantes en mi archivo app.config (Keys, XpathExpressions, etc.). Cuando ejecuto el exe compilado esto funciona muy bien. En el Shell interactivo este no es el caso.App.config y F # Interactive no funciona

He intentado copiar el archivo .config de mi bin/directorio de publicación en obj/Debug & obj/Release dirs, pero la llamada a ConfigurationManager.AppSettings.Item("key") siempre devuelve null.

¿Alguna sugerencia de cómo solucionar esto?

Con recuerdos

Respuesta

0

El problema es que el FSI es un exe diferente correr detrás de las escenas y hace algunos trucos loco con la compilación de la marcha y la generación de binarios. Compruebe para ver qué assembly FSI thinks is running. Puede que se sorprenda de lo que encuentre :)

Se generará un error:

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

Es necesario examinar la manera de obtener la configuración app.config en conjuntos dinámicos. Esto podría ser un dolor y no valdría la pena. Si funciona como un binario compilado, probaría aquellas cosas que dependen de la configuración de configuración fuera de FSI.

Buena suerte.

0

Quizás podría apuntar FSI al archivo app.config manualmente usando OpenMappedExeConfiguration method en ConfigurationManager.

También podría intentar cargar su ensamblaje en un Dominio de aplicación separado: puede asignar cualquier archivo como archivo de configuración a un Dominio de aplicación que cree usted mismo utilizando la clase AppDomainSetup.

hecho de Th sigue siendo que el FSI no se adapta bien a este tipo de escenario ...

12

Mientras FSI genera dinámicamente el código para su entrada, utilizando la fsi.exe.config funcionará bien.

creé este archivo:

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

y lo ha guardado como "fsi.exe.config" (archivos de programa \ FSharp-version \ bin).

Luego comenzó 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" 

También trabajó desde Visual Studio. (Pero tenga en cuenta que tendrá que reiniciar la sesión a los cambios de recogida.)

+0

esto funcionó para mí. Quería agregar " .. .." para un cliente WCF. Agregué esto al "fsi.exe.config" existente, reinicié FSI, y luego mi "cliente let = new ServiceClient" funcionó :) –

+0

Para VS 2015, las configuraciones de F # se encuentran en 'C: \ Archivos de programa (x86) \ Microsoft SDKs \ F # \ 4.0 \ Framework \ v4.0'. –

+0

el verdadero inconveniente de este enfoque es tener que poner el archivo de configuración en esa ubicación (para scripts fsx, la mejor solución sería si el archivo de configuración pudiera ubicarse en la misma carpeta que el script, como se solicita en http: // stackoverflow.com/questions/13256167/use-app-config-from-fsx-file) – knocte

13

F # Interactivo puede trabajo con los ejecutables que se basan en app.config archivos.

La manera de hacer esto es tener un archivo .fs en su proyecto que carga el .config condicionada a la COMPILED definen así:

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 

continuación, en su referencia archivo de comandos ejecutable y #load el archivo .fs por lo :

#I "../Build/Path

#r "ConfiguredApp.exe"

#load "MyConfig.fs"

En la ejecución de estas tres líneas, verá un mensaje similar al siguiente en la ventana FSI:

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

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

en cuenta que en realidad está haciendo referencia a la app.config cuando está en FSI (en lugar de .exe.config generado)

mejor de la suerte ...

0

Creo que proporciono a continuación lo mejor de ambos mundos de los dos más votados respuestas anteriores (especialmente para las personas que escriben guiones FSX):

Teniendo en cuenta este archivo app.config:

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

Leer foo esta manera:

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) 
Cuestiones relacionadas