2011-09-26 14 views
23

Desde la versión 3.0, .NET instala un grupo de diferentes 'ensamblados de referencia' en C: \ Archivos de programa \ Conjuntos de referencia \ Microsoft ...., para admitir diferentes perfiles (por ejemplo, perfil de cliente .NET 3.5, perfil de Silverlight). Cada uno de estos es un ensamblado .NET apropiado que contiene solo metadatos, sin código IL, y cada ensamblaje está marcado con el ReferenceAssemblyAttribute. Los metadatos están restringidos a los tipos y miembros disponibles bajo el perfil correspondiente: así es como Intellisense muestra un conjunto restringido de tipos y miembros. Los ensambles de referencia no se utilizan en tiempo de ejecución.¿Cómo creo y uso un "Ensamblaje de referencia" de solo metadatos .NET?

Me enteré un poco al respecto desde this blog post.

Me gustaría crear y usar un conjunto de referencia para mi biblioteca.

  1. ¿Cómo creo un ensamblado solo de metadatos? ¿Hay algún indicador de compilador o postprocesador ildasm?
  2. ¿Hay atributos que controlan qué tipos se exportan a diferentes 'perfiles'?
  3. ¿Cómo funciona la resolución del conjunto de referencia en tiempo de ejecución? Si tuviera el conjunto de referencia presente en mi directorio de aplicaciones en lugar del ensamblado "real", y no en el GAC, continuaría la prueba y se desencadenaría mi evento AssemblyResolve para que puede suministrar el ensamblaje real en tiempo de ejecución?

Cualquier idea o consejos sobre dónde podría obtener más información sobre esto sería muy apreciada.

Actualización: Mirando a su alrededor un poco, veo el .NET 3.0 '' ensamblados de referencia parecen tener algo de código, y la única Reference Assembly attribute se añadió en .NET 4.0. Entonces, el comportamiento podría haber cambiado un poco con el nuevo tiempo de ejecución.

¿Por qué? Para mi biblioteca de complementos de Excel-DNA (http://exceldna.codeplex.com), creo el complemento .xll de un solo archivo empaquetando los ensamblados a los que se hace referencia en el archivo .xll como recursos. Los ensamblados empaquetados incluyen el código de complemento del usuario, así como la biblioteca administrada Excel-DNA (que puede ser referenciada por el ensamblado del usuario).

Suena bastante complicado, pero funciona maravillosamente bien la mayor parte del tiempo: el complemento es un solo archivo pequeño, por lo que no hay problemas de instalación de distribución. Me encuentro con problemas (no inesperados) debido a las diferentes versiones: si hay una versión anterior de la biblioteca administrada Excel-DNA como archivo, el tiempo de ejecución cargará eso en lugar del empaquetado (nunca tengo la oportunidad de interferir con el cargando).

Espero hacer un ensamblaje de referencia para mi parte administrada Excel-DNA que los usuarios pueden señalar al compilar sus complementos. Pero si erróneamente tienen una versión de este ensamblado en tiempo de ejecución, el tiempo de ejecución no debería cargarlo, y darme la oportunidad de cargar el ensamblaje real de los recursos.

+1

¿Por qué quieres hacer eso? – svick

Respuesta

9

Para crear un conjunto de referencia, deberá añadir esta línea a su archivo AssemblyInfo.cs:

[assembly: ReferenceAssembly] 

Para cargar otros, se puede hacer referencia a ellos como de costumbre a partir de las referencias del proyecto VisualStudio, o dinámicamente en tiempo de ejecución usando:

Assembly.ReflectionOnlyLoad()

o

Assembly.ReflectionOnlyLoadFrom()


Si ha añadido una referencia a una de metadatos/referencia de ensamblado utilizando VisualStudio, a continuación, IntelliSense y la construcción de su proyecto trabajará muy bien, sin embargo, si se intenta ejecutar su aplicación contra uno, obtendrá un error:

System.BadImageFormatException: Cannot load a reference assembly for execution.

Así que la expectativa es que en tiempo de ejecución que le sustituya en un montaje real que tiene la misma firma de metadatos.

Si ha cargado un ensamblaje dinámicamente con Assembly.ReflectionOnlyLoad(), entonces solo puede realizar todas las operaciones de reflexión contra él (lea los tipos, métodos, propiedades, atributos, etc., pero no puede invocar dinámicamente ninguno de ellos).


Tengo curiosidad por saber cuál es su caso de uso para crear un conjunto de solo metadatos. Nunca tuve que hacer eso antes, y me encantaría saber si ha encontrado algún uso interesante para ellos ...

+2

que componen un ** ejemplo inventado **: puede crear una imagen nativa de un ensamblado .NET usando, p. Mono mkbundle.exe. Ahora aún podría querer permitir que los dlls de plugins accedan a la interfaz pública del ensamblaje original. Estoy seguro de que puedes hacer que funcione de esta manera. En todo caso, daría como resultado _realmente_ ofuscado y _large_ assemblies :) – sehe

+0

Agregar el atributo ReferenceAssembly no cambia el resultado a un ensamblado de solo metadatos como los ensamblados de referencia de .NET 4. Estoy tratando de descubrir cómo se construyen. Tendré que intentarlo, pero después de manejar BadImageFormatException, ¿cree que la resolución de ensamblado llamará a mi controlador AssemblyResolve? (Añadiré detalles de mi caso de uso a la pregunta.) – Govert

+0

He agregado información sobre por qué estoy interesado. @sehe no está lejos de la marca! Esos ensamblajes empaquetados son realmente pequeños, ya que los comprime antes de embalarlos, y los ensamblajes CLI se comprimen muy bien. El resultado está ofuscado solo en el sentido de "oscuridad": los ensamblados .NET no están en su cara, por lo que debe trabajar un poco antes de señalarlos con ILSpy. Pero un ofuscador de ese tipo sería otro buen caso de uso. – Govert

2

Sí, esto es nuevo para .NET 4.0. Estoy bastante seguro de que esto se hizo para evitar los desagradables problemas de versiones en los paquetes de servicio .NET 2.0. El mejor ejemplo es la sobrecarga WaitHandle.WaitOne (int), agregada y documentada en SP2. Una sobrecarga popular porque evita tener que adivinar el valor correcto para * exitContext "en la sobrecarga de WaitOne (int, bool). El problema es que el programa se dispara cuando se ejecuta en una versión de 2.0 que es anterior a SP2. ya sea de diagnóstico. el aislamiento de los conjuntos de referencia asegura que esto no puede suceder de nuevo.

yo creo esos conjuntos de referencia se crearon partiendo de una copia de los ensamblados compilados (como se hizo en las versiones anteriores) y ejecutarlos a través de una herramienta que elimina el IL del ensamblado. Sin embargo, esa herramienta no está disponible para nosotros, no hay nada en las carpetas bin/netfx 4.0 del subdirectorio SDK de Windows 7.1 que podría hacer esto. No es exactamente una herramienta que se usa con frecuencia, así que probablemente no calidad de producción :)

+0

¡Ah! Creo que esa es la herramienta que estoy buscando ... – Govert

+1

Hans, creo que esa herramienta se usa con más frecuencia de lo que crees. Los ensamblados de solo metadatos también se utilizan para iniciar los ensamblados de .Net Framework, como se explica en [esta respuesta] (http://stackoverflow.com/questions/1316518/z/1316587) a una pregunta sobre cómo compilan .Net. Asambleas marco. Por supuesto, hay otros cambios realizados a través de herramientas especiales para esos ensamblajes, como los tipos primitivos que tienen referencias al miembro 'm_value' reemplazado por referencias a' this'. –

+0

Gracias Kevin por el puntero a la otra pregunta. Entonces esos ensambles de referencia son conjuntos de metadatos solo deshidratados. – Govert

1

Puede tener suerte con la Biblioteca Cecil (de Mono); Creo que la implementación permite la funcionalidad de ILMerge, también podría escribir ensamblajes de solo metadatos.

He escaneado el código base (documentación es escasa), pero no he encontrado ninguna pista obvias sin embargo ...

YYMV

3

Si usted todavía está interesado en esta posibilidad, he hecho una bifurcación del proyecto il-reeck basado en Mono.Cecil que acepta un argumento de línea de comando "/ meta" para generar un ensamblado de metadatos solo para el público y tipos protegidos.

https://github.com/KarimLUCCIN/il-repack/tree/xna

(lo probé en XNA Framework completo y su trabajo que yo sepa ...)

+0

¡Gracias (también para publicar aquí)! Todavía interesado: echaré un vistazo cuando tenga la oportunidad. – Govert

Cuestiones relacionadas