2009-09-25 16 views
98

Estaba mirando la documentación de msdn y todavía estoy un poco confundido sobre cuál es exactamente la diferencia entre usar LoadFile y LoadFrom al cargar un ensamblaje. ¿Puede alguien proporcionar un ejemplo o una analogía para describirlo mejor? La documentación de MSDN me confundió más. Además, es ReflectionOnlyLoadFrom lo mismo que LoadFrom, excepto que carga el conjunto solo en modo de reflexión.¿Diferencia entre LoadFile y LoadFrom con .NET Ensambles?

Desde mi experiencia .NET no es la mejor, he aquí algunas preguntas con respecto a la documentación de MSDN usando LoadFile:

1) ¿Qué significa por LoadFile examina asambleas que tienen la misma identidad, pero se encuentran en diferentes ¿caminos? ¿Cuál es la identidad (ejemplo)?

2) Indica que LoadFile no carga archivos en el 'Contexto de LoadFrom' y no resuelve dependencias utilizando la ruta de carga. ¿Qué significa esto? ¿Alguien puede dar un ejemplo?

3) Por último, indica que LoadFile es útil en este escenario limitado porque LoadFrom no puede cargar ensamblajes que tienen las mismas identidades pero rutas diferentes; solo cargará la primera de esas asambleas, lo que nuevamente me lleva a la misma pregunta, ¿cuál es la identidad de las asambleas?

+6

En serio, también creo que a veces MS debe contratar mejores escritores o algo más, ya que las oraciones no son siempre comprensibles ... – Tarik

+7

Ver también [* undocumentation *] (http://www.codinghorror.com/blog/2005/ 11/avoiding-undocumentation.html) –

+0

@ColonelPanic MS puede decir que todo está documentado ... pero con un factor de ayuda de ceroooo. – Legends

Respuesta

80

¿Esto lo aclara?

// path1 and path2 point to different copies of the same assembly on disk: 

Assembly assembly1 = Assembly.LoadFrom(path1); 
Assembly assembly2 = Assembly.LoadFrom(path2); 

// These both point to the assembly from path1, so this is true 
Console.WriteLine(assembly1.CodeBase == assembly2.CodeBase); 

assembly1 = Assembly.LoadFile(path1); 
assembly2 = Assembly.LoadFile(path2); 

// These point to different assemblies now, so this is false 
Console.WriteLine(assembly1.CodeBase == assembly2.CodeBase); 

Editar: para responder a las preguntas que se plantean en la pregunta revisada, que debe de leer Suzanne Cook on Assembly Identity.

Existen muchas reglas que rigen cómo se cargan los ensamblados, y algunas tienen que ver con la forma en que resuelven las dependencias: si su AssemblyA depende de AssemblyB, ¿dónde debe buscar .NET para encontrar AssemblyB? En Global Assembly Cache, el mismo directorio que encontró AssemblyA, o en otro lugar completamente? Además, si encuentra copias múltiples de ese ensamblaje, ¿cómo debería elegir cuál usar?

LoadFrom tiene un conjunto de reglas, mientras que LoadFile tiene otro conjunto de reglas. Es difícil imaginar muchas razones para usar LoadFile, pero si necesita usar la reflexión en diferentes copias del mismo ensamblaje, está ahí para usted.

+1

¿Es CodeBase lo mismo que Identity? – Xaisoft

+0

No, acabo de utilizar CodeBase aquí como una propiedad arbitraria del ensamblado para ilustrar que la segunda instancia de ensamblado apuntaba al archivo 'incorrecto' (en el primer ejemplo). Estoy actualizando mi respuesta con más detalles. –

+0

Se borra un poco, pero ¿cómo path1 y path2 apuntan a diferentes copias del mismo ensamblado en el disco cuando se utiliza LoadFrom y cuando se utiliza LoadFile, path1 y path2 apuntan a diferentes ensamblajes. ¿Qué es un ejemplo de lo que serían path1 y path2? Gracias por su paciencia. – Xaisoft

50

De Suzanne Cook's blog:

LoadFile vs LoadFrom

Ten cuidado - no son la misma cosa .

LoadFrom() pasa a través de la fusión y se puede redirigido a otro conjunto de en un camino diferente pero con que misma identidad si uno es ya cargada en el contexto LoadFrom.

LoadFile() no se vincula a través de Fusion en absoluto: el cargador simplemente va adelante y carga exactamente * lo que solicitó el llamador . No utiliza ni en el contexto Cargar ni en Cargar desde .

Por lo tanto, LoadFrom() generalmente le da lo que ha pedido, pero no necesariamente. LoadFile() es para aquellos que realmente, realmente desean exactamente lo que se solicita. (* Sin embargo, a partir de v2, la política se ser aplicado tanto a LoadFrom() y LoadFile(), por lo LoadFile() no necesariamente ser exactamente lo que era solicitado. Además, a partir de v2, si un montaje con su identidad está en el GAC, la copia GAC ​​se utilizará en lugar uso ReflectionOnlyLoadFrom() para cargar exactamente lo que quiere -.. pero, nota que los montajes cargados de esa manera no se puede ejecutar)

LoadFile() tiene un truco. Dado que no utiliza un contexto de enlace, sus dependencias no están automáticamente en su directorio. Si no están disponibles en el contexto de carga, , tendría que suscribirse al evento AssemblyResolve para vincularlos al .

Ver here.

Ver también Choosing a Binding Context artículo en el mismo blog.

+0

Gracias, revisaré el blog, actualicé mi publicación con algunas preguntas sobre la documentación de msdn. – Xaisoft

+0

@Xaisoft - El blog de Suzanne Cook vuelve al rescate con la respuesta de una identidad de ensamblaje. Ver http://blogs.msdn.com/suzcook/archive/2003/07/21/57232.aspx. Es esencialmente un "nombre de visualización de conjunto" y es algo así como: "Sistema, Versión = 1.0.3300.0, Cultura = neutro, PublicKeyToken = b77a5c561934e089", por lo que incluye tanto el nombre real del ensamblado como su número de versión junto con otra información de identificación (como PublicKeyToken, etc.). – CraigTP

+0

Curioso, es Suzanne Cook la Reflejante Guru :) – Xaisoft

5

una diferencia que he notado es:

Assembly.LoadFile - Cargas de montaje en diferente dominio de aplicación con derechos de usuario limitadas (diffrence principel). operaciones como serilización/deserilización no pudieron realizarse.

Assembly.LoadFrom - Montaje de cargas en el mismo dominio de aplicación con los mismos derechos de usuario (mismo principel).

2

Nota: Si un ensamblaje se carga utilizando una ruta 8.3, y luego desde una ruta que no sea 8.3, se verán como ensamblajes diferentes, aunque sean la misma DLL física.

32

Después de muchos arañazos en la cabeza, he descubierto una diferencia esta tarde.

Quería cargar una DLL en tiempo de ejecución, y la DLL vivía en otro directorio. Esa DLL tenía sus propias dependencias (DLL) que también vivían en ese mismo directorio.

LoadFile(): carga el DLL específico, pero no las dependencias. Entonces, cuando se hizo la primera llamada desde el DLL a uno de esos otros DLL lanzó una excepción FileNotFoundException.

LoadFrom(): Cargué la DLL que especifiqué y también todas las dependencias que vivían en ese directorio.

+3

¡Ese era exactamente mi problema! Estaba obteniendo la 'FileNotFoundException' cuando creé una nueva instancia de un objeto definido en un ensamblado al que hacía referencia el ensamblaje que acababa de cargar con' .LoadFile'. Cambiar esto a '.LoadFrom' pareció solucionar el problema, ¡pero no sabía por qué! Gracias – Connell

+1

Gracias, estaba teniendo el mismo problema. –

0

En mi caso, simplemente tuve que eliminar el caché de la aplicación ASP ubicado en C:\Windows\Microsoft.NET\Framework\[asp version]\Temporary ASP.NET Files. Se reconstruye cuando el sitio se ejecuta por primera vez. Asegúrese de detener IIS primero.

Espero que esto ayude a alguien como lo hizo por mí.

-1

Según la documentación:

LoadFile (String): carga el contenido de un archivo de ensamblaje dado una ruta de archivo.

LoadFrom (String): Carga un ensamblado dado su nombre de archivo o ruta.

Cuestiones relacionadas