studio example ironpython

example - ¿Cómo usar IronPython con App.Config?



ironpython virus (6)

Tengo una solución de trabajo con código de muestra. Ver mi blog: http://technomosh.blogspot.com/2012/01/using-appconfig-in-ironpython.html

Requiere una clase de proxy especial que se inyecta al ConfigurationManager.

Aquí está la fuente de la biblioteca ConfigurationProxy:

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Configuration; using System.Configuration.Internal; using System.Xml; using System.Collections.Specialized; using System.Reflection; using System.IO; namespace IronPythonUtilities { /// <summary> /// A custom app.config injector for use with IronPython code that needs configuration files. /// The code was taken and modified from the great work by Tom E Stephens: /// http://tomestephens.com/2011/02/making-ironpython-work-overriding-the-configurationmanager/ /// </summary> public sealed class ConfigurationProxy : IInternalConfigSystem { Configuration config; Dictionary<string, IConfigurationSectionHandler> customSections; // this is called filename but really it''s the path as needed... // it defaults to checking the directory you''re running in. public ConfigurationProxy(string fileName) { customSections = new Dictionary<string, IConfigurationSectionHandler>(); if (!Load(fileName)) throw new ConfigurationErrorsException(string.Format( "File: {0} could not be found or was not a valid cofiguration file.", config.FilePath)); } private bool Load(string file) { var map = new ExeConfigurationFileMap { ExeConfigFilename = file }; config = ConfigurationManager.OpenMappedExeConfiguration(map, ConfigurationUserLevel.None); var xml = new XmlDocument(); using (var stream = new FileStream(file, FileMode.Open, FileAccess.Read)) xml.Load(stream); //var cfgSections = xml.GetElementsByTagName("configSections"); //if (cfgSections.Count > 0) //{ // foreach (XmlNode node in cfgSections[0].ChildNodes) // { // var type = System.Activator.CreateInstance( // Type.GetType(node.Attributes["type"].Value)) // as IConfigurationSectionHandler; // if (type == null) continue; // customSections.Add(node.Attributes["name"].Value, type); // } //} return config.HasFile; } public Configuration Configuration { get { return config; } } #region IInternalConfigSystem Members public object GetSection(string configKey) { if (configKey == "appSettings") return BuildAppSettings(); object sect = config.GetSection(configKey); if (customSections.ContainsKey(configKey) && sect != null) { var xml = new XmlDocument(); xml.LoadXml(((ConfigurationSection)sect).SectionInformation.GetRawXml()); // I have no idea what I should normally be passing through in the first // two params, but I never use them in my confighandlers so I opted not to // worry about it and just pass through something... sect = customSections[configKey].Create(config, config.EvaluationContext, xml.FirstChild); } return sect; } public void RefreshConfig(string sectionName) { // I suppose this will work. Reload the whole file? Load(config.FilePath); } public bool SupportsUserConfig { get { return false; } } #endregion private NameValueCollection BuildAppSettings() { var coll = new NameValueCollection(); foreach (var key in config.AppSettings.Settings.AllKeys) coll.Add(key, config.AppSettings.Settings[key].Value); return coll; } public bool InjectToConfigurationManager() { // inject self into ConfigurationManager var configSystem = typeof(ConfigurationManager).GetField("s_configSystem", BindingFlags.Static | BindingFlags.NonPublic); configSystem.SetValue(null, this); // lame check, but it''s something if (ConfigurationManager.AppSettings.Count == config.AppSettings.Settings.Count) return true; return false; } } }

y aquí es cómo se puede cargar desde Python:

import clr clr.AddReferenceToFile(''ConfigurationProxy.dll'') from IronPythonUtilities import ConfigurationProxy def override(filename): proxy = ConfigurationProxy(filename) return proxy.InjectToConfigurationManager()

Finalmente, una muestra de uso:

import configproxy import sys if not configproxy.override(''blogsample.config''): print "could not load configuration file" sys.exit(1) import clr clr.AddReference(''System.Configuration'') from System.Configuration import * connstr = ConfigurationManager.ConnectionStrings[''TestConnStr''] print "The configuration string is {0}".format(connstr)

Tengo una biblioteca de clases que generalmente se llama desde una consola .net o aplicación web. Se integra con varios componentes y se basa en un app.config o web.config.

Si quiero utilizar la biblioteca de clase de la secuencia de comandos (es decir, IronPython), ¿cómo puedo obtener la secuencia de comandos para utilizar el archivo de configuración? Idealmente, quiero poder elegir el archivo de configuración cuando ejecuto el script, o por convención (archivo de configuración junto al archivo de script).

No quiero cambiar el ipy.exe.config si es posible ya que esto no se escalaría para múltiples configuraciones sin tener varias copias de IronPython.

Alguna alternativa?


Traduciendo esta entrada del blog a Python, esto debería funcionar:

import clr import System.AppDomain System.AppDomain.CurrentDomain.SetData(“APP_CONFIG_FILE”, r”c:/your/app.config”)


Siempre puede incluir secciones adicionales dentro de los archivos de configuración. En su archivo ipy.exe.config, puede agregar un include para importar configuraciones de configuración externas; di myApp.config.

En un archivo por lotes / comando, siempre puede copiar sobre un conjunto .config específico en myApp.config y, por lo tanto, ejecutarlo con diferentes archivos de configuración bajo demanda.

Echa un vistazo a este blog sobre cómo lograr esto; http://weblogs.asp.net/pwilson/archive/2003/04/09/5261.aspx


Puede mirar la clase System.Configuration.ConfigurationManager . Más específicamente, el método OpenMappedExeConfiguration le permitirá cargar cualquier archivo .config de su elección. Esto le dará un objeto de Configuration que expone las propiedades estándar AppSettins, ConnectionStrings, SectionGroups y Sections.

Este enfoque requiere que pase el nombre del archivo de configuración a su secuencia de comandos como un argumento de línea de comando o que tenga una lógica de código para elegir el archivo .config en tiempo de ejecución.

No conozco Python, así que me abstendré de intentar publicar código de muestra. :-)


Para una solución, lo que hice fue llenar la colección de AppSettings para la clase estática de ConfigurationManager "manualmente", así que creé un script PY y ejecuté una "importación" de él en IronPython y la configuración estará disponible para la biblioteca de clases. Sin embargo, no pude asignar valores a la colección ConnectionStrings :(

Mi script se ve así

import clr clr.AddReferenceToFileAndPath(r''c:/WINDOWS/Microsoft.NET/Framework/v2.0.50727/System.configuration.dll'') from System.Configuration import * ConfigurationManager.AppSettings["settingA"] = "setting A value here" ConfigurationManager.AppSettings["settingB"] = "setting B value here"

Sin embargo, sería bueno saber cómo "cargar" un archivo .config personalizado en la clase ConfigurationManager.


Intenté seguir las respuestas anteriores, pero me pareció demasiado complejo. Si sabe exactamente qué atributo necesita de su archivo App.config, puede colocarlo directamente en el código. Por ejemplo, una DLL que importé necesitaba conocer el atributo AssemblyPath en mi archivo App.Config.

import clr import System.Configuration clr.AddReference("System.Configuration") from System.Configuration import ConfigurationManager ConfigurationManager.AppSettings["AssemblyPath"] = ''C:/Program Files (X86)/...

Esto era todo lo que necesitaba, y la biblioteca de clases a la que me estaba conectando podía ver el atributo AssemblyPath que necesitaba para ejecutar.