2009-05-08 16 views
11

Finalmente logré construir una solución funcional de una arquitectura de plugins con la ayuda de algunos tipos aquí, pero ahora surge un nuevo problema.Plugin para usar su propia app.config

Mi aplicación de alojamiento utiliza su archivo app.config para algunos valores predeterminados para el ensamblaje en ejecución (que es un servicio de Windows).

Cada complemento debe poder cargar su propia configuración desde un archivo de configuración de complementos distinto, ya que el host no debe conocer la configuración del complemento. En el proyecto de complemento también agregué un archivo app.config (con algunas configuraciones y una cadena de conexión) para poder instanciar la clase Properties.Settings y usar sus propiedades en el código del complemento.

El problema es cuando cambio la configuración en el app.config del plugin (que está compilado como plugin.dll.config) No puedo ver esos cambios en el plugin en sí, que todavía usa la configuración del tiempo de diseño .

¿Hay alguna forma de cargar la configuración de app.config en cada complemento para que la clase de propiedades generadas generada funcione? Si no, ¿hay otra forma de cargar un archivo de configuración basado en app.config en el complemento? Estoy planeando agregar un método LoadConfiguration en la interfaz de IPlugin para que cada complemento cargue su propia configuración.

Respuesta

2

¿Algo como ConfigurationManager.OpenMappedExeConfiguration ayuda aquí? Puede crear un objeto de Configuración leyendo en los valores de un archivo específico.

+0

De hecho, lo intenté, pero de alguna manera esto no parece funcionar. –

+0

Otro problema que impide que esto funcione es que tendrá una instancia de configuración, pero la clase Properties.Settings generada no funcionará. –

3

Estás trabajando en contra de la arquitectura de app.config. Obtiene un archivo app.config por ejecutable (EXE, no DLL). El ejecutable se inicia, crea su AppDomain y luego carga MyApp.exe.config. Puede agregar objetos app.config todo lo que desee en Visual Studio, pero se ignoran para las DLL. Creo que lo que quiere hacer es copiar manualmente el XML de dll.config y pegarlo en el nivel de la aplicación app.config. (Estoy seguro de que hay una manera de automatizar esto usando TeamBuild o algo así.) Los valores reemplazados estarán entonces disponibles para su clase Properties.Settings.

+0

Sí, pero la pregunta indica claramente que la aplicación no debe tener en cuenta la configuración del complemento. – ChrisF

+0

Cierto, sin embargo, estaría satisfecho si de alguna manera puedo inyectar dinámicamente la configuración del complemento en el archivo de configuración principal de app.config en el tiempo de ejecución. El problema aquí es que también necesito el capítulo de configuración de conexión de los archivos app.config de mis complementos ya que casi todos funcionan en las bases de datos de SQL Server. –

+0

Si cada complemento se creó en su propio Dominio de aplicación (generalmente es una buena idea que aparezca de otras publicaciones en SO), entonces es posible que pueda convencerlo de que cargue un archivo de configuración diferente para el nuevo AppContext. –

2

Prefiero construir y usar un complemento de tipo IConfigManager. Su trabajo es abstraer cómo se almacena la configuración. Recibe una instancia de esto a través de inyección de dependencia. De esta forma, la implementación de IConfigManager puede cargar configuraciones desde múltiples archivos .config, desde la red, desde una base de datos o cualquier otra fuente. También lo uso para proporcionar valores predeterminados basados ​​en el usuario, la máquina y/o la aplicación, que pueden ser anulados por el usuario, p. color de fondo, fuente, etc.

Otras ventajas de este método son que las configuraciones pueden conservarse de manera uniforme en todos los complementos; sin que los complementos tengan que preocuparse, el lugar donde el complemento almacena su configuración puede cambiar de forma transparente (desde. config to other) y, por último, el IConfigManager se puede burlar durante la prueba unitaria para simular diferentes situaciones.

Espero que ayude.

+0

Estoy intrigado por este enfoque. ¿Podría publicar un ejemplo o un enlace a un ejemplo? – HitLikeAHammer

+0

Hola Rick, No estoy seguro de que pueda exprimir mucho de un ejemplo en este comentario. No tengo un enlace a nada específico de esta respuesta: podría escribir una publicación de blog si tuviera un blog. ¿Hubo alguna parte de lo que dije sobre la que quisiera obtener más información? Veré si puedo configurar un blog en algún lugar y escribir sobre esto, pero no será rápido. Saludos. –

1

Soy un colega de Erik. Como va a estar en unas merecidas vacaciones las próximas semanas elaboraré un poco más sobre este tema.

En nuestros complementos, utilizamos varias instancias de clientes del servicio WCF. Lo bueno de estos servicios es que vienen con secciones de app.config que se pueden usar para configurar el comportamiento, tipo de servicio, seguridad, etc.

Ahora cuando cargamos nuestros complementos, estas secciones faltan en config y por lo tanto, no se pueden encontrar los puntos finales correctos. Por supuesto, podríamos establecerlos en código, pero ese tipo de golpes la capacidad de establecer otras opciones de configuración en el camino cuando sea necesario. Es posible que deseemos implementar ws-security por ejemplo.

Así que necesitamos una forma de cargar estas configuraciones para que los complementos puedan leer sus respectivas configuraciones. Por supuesto, podríamos fusionar todas las configuraciones en una sola, pero ese tipo de método elimina el método de "solo complemento", ya que tendría que administrar las configuraciones junto con la instalación del complemento.

Pensé en crear una pequeña herramienta que fusionaría la configuración 'maestra' con todas las configuraciones colocadas en un subdirectorio del proyecto y reemplazaría el archivo .exe.config con esa. Creo que eso funcionaría, pero me preguntaba si .NET no ofrece mejores opciones. Múltiples AppDomains no es algo que funcione porque los complementos tienen que interactuar (modelo de proveedor/consumidor) entre sí y no queremos cambiar a la comunicación remota solo por este problema.

Actualización: He solucionado la mayoría de los problemas al usar el ConfigurationManager para abrir las configuraciones existentes y leer las configuraciones de la aplicación. En cuanto a los clientes de WCF; puede cargar la configuración de punto final/enlace para el servidor y el cliente como se encuentra aquí: http://weblogs.asp.net/cibrax/archive/2007/10/19/loading-the-wcf-configuration-from-different-files-on-the-client-side.aspx

+0

¿Sabía que es posible hacer referencia a un archivo .config externo desde la aplicación principal.config/web.config? De esta forma, puede mantener la configuración de su plugin en un archivo separado y simplemente agregar una referencia a la configuración principal. De todos modos, tienes que registrar los complementos de alguna manera, así que no veo que esto sea un gran problema. – Aaronaught

1

Puede hacer que cada conector lea su propia sección de configuración y luego en el archivo de configuración principal utilice la configuración ConfigSource para apuntar a un archivo externo. (Consulte este link para obtener más información)

No puede evitar por completo tener información sobre la configuración del complemento en el archivo principal app.config, pero al menos las configuraciones específicas del complemento se encuentran en archivos separados.

0

Por lo general, prefiero evitar toda la confusión de la aplicación mediante la creación de un archivo Xml dedicado que el host procesa con la configuración del complemento también dentro. El código XML sería algo como esto:

<root> 
    <Settings> 
     Here's where anything specific to the app goes. 
    </Settings> 
    <plugins> 
     <plugin type="mylibrary.myclass"> 
      Here I let the plugin serialize itself however it wants to. 
     </plugin> 
    </plugins> 
</root> 

la aplicación de alojamiento a continuación, crea el plugin desde el tipo de atributo y pruebas si la clase implementa ISerializable; si lo hace, entonces el complemento se deserializará. Da un poco de miedo tener los complementos alineados con la configuración de la aplicación, pero si carga la subcadena de Xml del complemento en un nuevo XmlReader, entonces no tiene que preocuparse de que un error en el complemento lea demasiado en el Xml cuerda.

Cuestiones relacionadas