.net - reglas - tipos de montaje de mesas para restaurante
Reglas de montaje de montajes referenciados. (4)
¿Qué reglas sigue VS (msbuild?) Durante la compilación de la solución? ¿En qué casos se copiarán asemblies con referencias indirectas a la carpeta de salida y en cuáles no?
Acabo de experimentar un poco, y parece que se copiará cualquier ensamblaje de referencia indirecta que tenga un tipo referenciado directamente por código en otro ensamblaje. Si no hay nada en el código, no lo será. Aquí está mi ejemplo de escenario:
Programa principal: aplicación de consola con una referencia directa a DirectAssembly. Código en Principal:
var foo = new DirectAssembly.SampleClass();
DirectAssembly: biblioteca de clases con una referencia directa a IndirectAssembly. Contiene
SampleClass
:public class SampleClass { // Comment out this line to change the behaviour... IndirectAssembly.IndirectClass neverUsed = null; public SampleClass() { object x = Activator.CreateInstance("IndirectAssembly", "IndirectAssembly.IndirectClass"); } }
IndirectAssembly: contiene una clase pública
IndirectClass
con un constructor público sin parámetros
Como se describió anteriormente, funciona porque el montaje indirecto se copia en la carpeta de salida de MainProgram. Si comenta la línea indicada en SampleClass, IndirectAssembly no se copia (aunque sigue siendo una referencia) y el código fallará en el momento de la ejecución.
No estoy diciendo que estas sean todas las reglas, pero son al menos un comienzo ...
Debe copiar todas las referencias recursivas. Por ejemplo:
--- EDITAR ---
Las reglas (al menos en VS2010) parecen ser las siguientes:
- Una referencia indirecta se copia solo si se usa realmente.
- Se copia una referencia directa sin importar qué, incluso si no se utiliza realmente.
Por lo tanto, si desea asegurarse de que el ensamblaje requerido para la reflexión esté implementado, haga referencia al mismo desde el proyecto raíz.
Dejando de lado las reflexiones, parece ser suficiente simplemente agregar el conjunto mínimo de referencias en cada nivel de la jerarquía del proyecto.
Existe una sutileza que no se aborda en las respuestas anteriores, es decir, si el ensamblaje al que se hace referencia está en el GAC.
Considere un proyecto que haga referencia al ensamblaje A, que a su vez depende de los ensamblajes B y C. El ensamblaje C sucede que ha sido instalado en el GAC por algún "otro producto". Descubrí que Visual Studio 2013 copia A y B, pero no C, a la carpeta de salida, porque C ya está en la GAC. Si luego ejecuto la aplicación en una máquina que no tiene "otro producto" instalado, obtengo un error de enlace en tiempo de ejecución.
También me he dado cuenta de que la documentación de Microsoft en esta área parece ser incorrecta, al menos para VS2013.
Gestión de referencias de proyectos estados
Si implementa una aplicación que contiene una referencia a un componente personalizado que está registrado en la GAC, el componente no se implementará con la aplicación, independientemente de la configuración de CopyLocal. En versiones anteriores de Visual Studio, podría establecer la propiedad CopyLocal en una referencia para asegurarse de que se implementó el ensamblaje. Ahora, debe agregar manualmente el ensamblaje a la carpeta / Bin
Mis pruebas con VS2013 muestran que, contrariamente a lo anterior, CopyLocal = True siempre copia el ensamblaje al que se hace referencia directamente en la carpeta de salida, independientemente de si está en el GAC. Pero los ensamblajes con referencias indirectas parecen copiarse solo si no están en el GAC.
Este comportamiento significa que para asegurarse de que los ensamblados con referencia indirecta se implementan con su aplicación, debe agregar referencias explícitas a ellos, con CopyLocal = True (o copiarlos manualmente). Tenga en cuenta que, por defecto, CopyLocal se establecerá en False si el ensamblaje está en la GAC.
Mi experiencia es que copia todos los ensamblajes directamente referenciados, recursivamente, es decir, cualquier referencia directa en su código, y todo lo que estos también mencionan.
No se hará referencia a nada que no esté referenciado en el momento de la compilación en su código. Por lo tanto, las referencias que solo se resolvieron en tiempo de ejecución no se copiarán. Esto se debe a que, aunque sepa exactamente a qué se refiere, el copmpiler no. Ya sea la reflexión o el uso del activador para referenciarlo (como en las dos respuestas ya dadas) porque en el momento de la compilación, no se puede determinar el tipo real de los objetos.
Las referencias en el proyecto indican dónde se deben resolver las referencias de código, pero eso es todo (creo que la evidencia es que no se copiarán) todo se basa en las referencias codificadas en tiempo de compilación.
Esta es una de las razones por las que algunas de las técnicas de inyección pueden funcionar, antes de que la resolución de la referencia no tenga que realizarse en el momento de la compilación o incluso del despliegue.