2009-02-09 21 views
20

Tengo una biblioteca de clase C# y un proyecto de inicio (una aplicación de consola). La biblioteca de clases incluye una referencia de servicio a un servicio web. Cuando trato de ejecutar el proyecto, obtengo una InvalidOperationException porque el proyecto de inicio no está leyendo el archivo app.config de la biblioteca de la clase, y está ignorando la referencia del servicio. Para que funcione, me veo obligado a agregar la misma referencia de servicio al proyecto de inicio. ¿Hay alguna manera de evitar esto? ¿Puedo hacer que el proyecto de inicio reconozca la referencia de servicio de la biblioteca de clase y app.config sin tener que copiarlo al proyecto de inicio?Incluyendo una referencia de servicio de una biblioteca de clase

He intentado agregar un enlace a la aplicación.config de la biblioteca de clases, pero eso no funciona. La biblioteca de clases no es muy portátil si requiere que alguien lo use para agregar esa referencia de servicio al proyecto de inicio.

+0

+1 : Hola Zarjay, iba a hacer la misma pregunta. Aunque estoy de acuerdo con Andrew Hare, y entiendo por qué esto no es posible, también estoy de acuerdo en que la solución realmente no hace que la Biblioteca sea muy portátil. Me pregunto, ¿la configuración de configuración se puede aplicar programáticamente? – andy

+0

No estoy seguro, pero lo dudo. Impresionante idea, sin embargo. Sé que es posible escribir en el archivo de configuración, pero apuesto a que, en el momento en que tu código sea capaz de hacerlo, probablemente sea demasiado tarde para agregar una referencia de servicio. –

Respuesta

14

Piense en lo que estamos tratando de hacer - que tiene dos conjuntos que están construyendo:

Library 
ConsoleApp 

Ambas asambleas tienen archivos de configuración - Me imagino que se ven algo como esto:

Library 
    app.config 
ConsoleApp 
    ConsoleApp.exe.config 

Cuando ejecuta ConsoleApp no tiene forma de leer o saber desde app.config desde su ensamblaje Library. El único archivo de configuración que conoce o que le interesa es ConsoleApp.exe.config. Ahora es posible hacer que los archivos de configuración se refieran entre sí, pero esta no es la solución adecuada para lo que estás tratando de hacer.

Dado que su ensamblaje Library no tiene punto de entrada, nunca se cargará en un Dominio de aplicación. Como nunca se cargará en un AppDomain, su archivo de configuración de la aplicación nunca se usará.

Lo que debe hacer es referencia Library en ConsoleApp a través de una referencia de proyecto. A continuación, mueva todos los datos de configuración relevantes de app.config al ConsoleApp.exe.config ya que este es el archivo de configuración que utilizará su aplicación.

Esto le permitirá tener a dos cosas que hay que llamar a los métodos de su servicio web

  1. El código en Library que puede enviar y recibir mensajes SOAP.
  2. Los metadatos de configuración requeridos por Library para funcionar.
+0

Gracias por la explicación; tiene sentido ahora por qué no estaba funcionando. Todavía soy nuevo en .NET, y aunque prefiero que la biblioteca de clases sea un módulo autónomo cuya implementación interna es irrelevante para el código que lo está utilizando, ahora entiendo por qué no funciona en esta situación. –

+0

Por lo que vale, los datos de configuración no son una implementación interna: son los datos de configuración de la biblioteca que debe proporcionar el usuario de la biblioteca (su aplicación de consola). Mi práctica general es proporcionar el texto de configuración de muestra en una app.config con el proyecto de la biblioteca cuando se requiere un archivo de configuración, luego asumir que el usuario de la biblioteca copia esos datos de configuración en su propio archivo de configuración, realizando cambios como apropiado. Si el archivo de configuración no es requerido, esas opciones solo se convierten en perillas de configuración programáticas en la biblioteca. –

+7

Greg, no estoy de acuerdo. Los datos de configuración de la biblioteca equivaldrían a una URL del servicio web que el desarrollador conocería, no el usuario. El usuario no debería tener que importar qué es esa URL; es una implementación interna de una biblioteca, y como usuario de la interfaz (la biblioteca), no me importan los detalles de la implementación (el servicio web que está utilizando). Gracias a Dios que puedo usar las bibliotecas de clientes de Google de Google sin importar las URL que usa para realizar sus funciones. Lamentablemente, si hubiera una versión de .NET, me vería obligado a preocuparme. No tener esta opción es un gran defecto en .NET en mi opinión. –

0

Solo tiene que copiar la clave de configuración, apuntando al servicio, desde el archivo de configuración de la biblioteca de la clase hasta el archivo de configuración de la aplicación de la consola.

+0

Mi app.config no tiene una clave de configuración. ¿Cómo especifico uno? –

+0

Cuando haga referencia a un servicio web, puede elegir usar una referencia estática o dinámica, ver propiedades. Elegir dinámico hace que el IDE genere código, en su clase proxy de servicio web, para leer la url del archivo de configuración. Copie los valores generados en la configuración de la biblioteca en la configuración de la aplicación de su consola. –

0

Creo que sería más confuso si tuviera varios archivos de configuración en ejecución.

Si una biblioteca tiene elementos configurables, esperaría tener que poner esa configuración en mi archivo de configuración para consumir correctamente la biblioteca.

1

Puede copiar las partes relevantes de la aplicación.config de la configuración de la biblioteca de la clase en el app.config para la aplicación de la consola.

Alternativamente, si realmente está tratando de hacer esto realmente portátil, tendrá que pensar en otra forma de referenciar la dirección para la referencia del servicio específico dentro de la biblioteca de la clase.

+0

He intentado copiar sobre la aplicación.config, pero la aplicación de la consola no se ejecutará a menos que agregue también la referencia del servicio. La portabilidad realmente no es una prioridad; Me resulta molesto incluir algo redundantemente en un proyecto. La biblioteca de la clase debe ser autónoma. –

+0

Las bibliotecas de clase que son WCF-clients no son deliberadamente independientes. Por lo general, no están destinados a la redistribución. Están destinados a ser configurables en el extremo del cliente, por lo que la aplicación.config es típica para estos. Siempre puedes codificar el valor, pero eso es ... bueno ... codificación difícil. :) –

3

Una alternativa al uso de una referencia de servicio en la biblioteca de clases y luego copiar la configuración sería usar eventos de compilación que invoquen a svcutil.exe. Lo que me gusta de esto es que no tiene que hacer "actualizar el servicio de referencia" cuando cambia el servicio. Se actualizará automáticamente.

En la biblioteca de clases, utilice un evento de acumulación que sólo genera el código proxy:

svcutil.exe net.tcp://localhost:3315/MyService/mex /noConfig 

En la aplicación, utilice un evento de generación que genera la config. Puede usar la opción/mergeConfig para fusionarla en una app.config existente.

svcutil.exe net.tcp://localhost:3315/MyService/mex 
      /config:App.config /mergeConfig 

Si no desea conseguir un error de compilación si el servicio no está en funcionamiento, poner esto en el archivo de proyecto y obtendrá una advertencia en lugar de un error:

<Target 
    Name="PreBuildEvent" 
    Condition="'$(PreBuildEvent)'!=''" 
    DependsOnTargets="$(PreBuildEventDependsOn)"> 
    <Exec WorkingDirectory="$(OutDir)" 
     Command="$(PreBuildEvent)" 
     ContinueOnError="true" /> 
</Target> 
Cuestiones relacionadas