¿Qué reglas sigue VS (msbuild?) Durante la compilación de la solución? ¿En qué casos copiará los ensamblajes indirectamente referenciados a la carpeta de salida y en cuál no?Reglas de los ensamblados a los que se hace referencia copia
Respuesta
acabo de estar un poco de experimentación, y parece que ninguna asamblea indirectamente referencia que tiene un tipo directamente referenciado por código en otra asamblea será copiado. Si no hay nada en el código, no lo será. Aquí está mi escenario de ejemplo:
MainProgram: aplicación de consola con una referencia directa a DirectAssembly. Código de principal:
var foo = new DirectAssembly.SampleClass();
DirectAssembly: biblioteca de clase 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 sin parámetros pública
Como se describió anteriormente, que funciona porque IndirectAssembly se copia en la carpeta de salida de MainProgram. Si comenta la línea indicada en SampleClass, IndirectAssembly es no copiado (aunque siga siendo una referencia) y el código fallará en el momento de la ejecución.
No estoy diciendo que estos son todos las reglas, pero son, al menos, un comienzo ...
Debe copiar todas las referencias recursivas. Por ejemplo:
--- --- EDITAR
Las reglas (al menos en VS2010) parece ser como sigue:
- una referencia indirecta se copia solo si se usa realmente
- Se copia una referencia directa sin importar qué, incluso si no se usa realmente.
Por lo tanto, si desea asegurarse de que se implementa el ensamblado requerido para la reflexión, hágalo desde el proyecto raíz.
Por cuestiones de reflexión, parece ser suficiente agregar el conjunto mínimo de referencias en cada nivel de la jerarquía del proyecto.
y ¿qué ocurre si se elimina el uso del conjunto de C (pero se mantiene la referencia) de B? No copiará el ensamblaje C. ¿Y qué ocurre si se usa el conjunto C por reflexión? No copiará el conjunto C – SiberianGuy
@Idsa: Sí, eso es exactamente lo que estaba escribiendo también. –
@Idsa El punto acerca de la reflexión es válido. En cuanto a mantener la referencia "innecesaria" de B a C, es cierto que la C no se copiará a 'bin', pero tampoco habrá ** error ** en tiempo de ejecución. –
Mi experiencia es que copia los montajes de todos directamente referenciados de forma recursiva, - es decir, nada directamente referenciado en su código, y cualquier cosa que estos referencia también.
No se hará referencia a todo lo que no se haga referencia en tiempo de compilación en su código. Por lo tanto, las referencias que solo se resuelven en tiempo de ejecución no se copiarán. Esto se debe a que, aunque puede saber exactamente a qué se refiere, el copmpiler no. Ya sea reflejando o usando el activador para referenciarlo (como en las dos respuestas ya dadas) porque en tiempo de compilación, no se puede determinar el tipo real de los objetos.
Las referencias en el proyecto indican dónde deben resolverse las referencias de código, pero eso es todo, creo que la evidencia es que no se copiarán, todo está basado en las referencias codificadas de tiempo de compilación.
Esta es una razón por la cual algunas de las técnicas de inyección pueden funcionar, antes de que la resolución de la referencia no sea necesaria en el momento de la compilación o incluso del despliegue.
Hay una sutileza no abordada en las respuestas anteriores, es decir, si el ensamblaje al que se hace referencia está en el GAC.
Considere un proyecto que hace referencia al ensamblaje A, que a su vez depende de los ensamblajes B y C. El ensamblaje C resulta haber 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 el GAC. Si luego ejecuto la aplicación en una máquina que no tiene "otro producto" instalado, obtengo una falla de enlace de tiempo de ejecución.
También he notado que la documentación de Microsoft en esta área parece estar equivocada, al menos para VS2013.
Managing Project References estados
Si implementa una aplicación que contiene una referencia a un componente personalizado que se registra en el GAC, el componente no serán desplegados con la aplicación, independientemente de la configuración CopyLocal. En versiones anteriores de Visual Studio, podía establecer la propiedad CopyLocal en una referencia para asegurarse de que se implementó el ensamblado. Ahora, debe agregar manualmente el conjunto a la carpeta \ Bin
Mis pruebas con espectáculo de VS2013 que, contrariamente a la, CopyLocal = True siempre copia el conjunto anterior hace referencia directamente a la carpeta de salida, independientemente de ya sea en el GAC. Pero los ensambles de referencia indirecta parecen copiarse solo si no están en el GAC.
Este comportamiento significa que para asegurarse de que los ensamblados de referencia indirecta se implementan con la aplicación, debe agregar referencias explícitas a ellos, con CopyLocal = True (o cópielos manualmente). Tenga en cuenta que, de manera predeterminada, CopyLocal se establecerá en False si el ensamblaje está en el GAC.
- 1. Obtener las rutas de acceso de todos los ensamblados a los que se hace referencia
- 2. La vista basada en navaja no muestra los ensamblados a los que se hace referencia
- 3. ¿Por qué (a veces) tengo que hacer referencia a los ensamblados a los que hace referencia el ensamblaje al que hago referencia?
- 4. Referencia circular entre los dos ensamblados .NET
- 5. ¿Hay alguna manera de forzar que todos los ensamblados a los que se hace referencia se carguen en el dominio de la aplicación?
- 6. ¿Se deben firmar los ensamblados de interoperabilidad?
- 7. Adición de frascos que se hace referencia a Android build.xml
- 8. TeamCity no copia todas las bibliotecas a las que se hace referencia
- 9. AssemblyLoadException en postsharp, ¿problema con los argumentos de los archivos DLL a los que se hace referencia?
- 10. Eliminación de todos los registros de una tabla que no se hace referencia a otra tabla
- 11. ADFS v2.0: Encontrar errores a los que hace referencia el número de referencia
- 12. Determine los ensamblados cargados
- 13. Cómo eliminar una rama y todos los objetos a los que hace referencia
- 14. C# CompileAssemblyFromSource, agregue los ensamblados referenciados que necesita?
- 15. ayuda con TFS y archivos DLL a los que se hace referencia
- 16. ¿Puede heredar Visual Studio 2010 C++ la ruta de acceso de los proyectos a los que se hace referencia?
- 17. ¿Por qué los tipos a los que se hace referencia fuera de un espacio de nombres deben estar totalmente calificados?
- 18. guión fsx que hace referencia a un dll que hace referencia a muchos dll
- 19. Lista de todos los ensamblados .NET
- 20. La reflexión sobre los ensamblados provoca que Unity requiera Microsoft.Practices.ServiceLocation
- 21. GetReferencedAssemblies no devuelve todos los ensamblados
- 22. "Copiar local" no copia ensamblados en el directorio de salida
- 23. ¿Deserentando un puntero se hace una copia?
- 24. ¿Los objetos de clase interna no estáticos se recogen después de que ya no se hace referencia a ellos?
- 25. ¿Cómo y cuándo se toman las variables a las que se hace referencia en los métodos anónimos de Delphi?
- 26. ¿Los ensamblados .NET alguna vez cambian?
- 27. ¿Cómo obtener todos los tipos en un conjunto al que se hace referencia?
- 28. Hacer referencia a los ensamblados de "importación" de Python cuando se realiza una llamada desde IronPython en C#
- 29. ¿Cómo recorre los ensamblados cargados actualmente?
- 30. Visual Studio 2010: ensamblados de referencia que apuntan a una versión superior de Framework
+1 Si los tipos de otros ensambles se referencian directamente, se copiarán. He tenido ocasión de hacer referencias explícitas a tipos, que normalmente se cargarían dinámicamente para que se desplegaran. –
¡Pero no deberíamos tener que hacer esto! – binki
@binki: Estoy de acuerdo, es un problema, y con NuGet en ASP.NET 5 es mucho mejor. Pero al menos saber lo que se necesita ayuda ... –