¿Cómo cargo un ensamblado y todas sus dependencias en tiempo de ejecución en C# para Reflection?

StackOverflow https://stackoverflow.com/questions/59220

  •  09-06-2019
  •  | 
  •  

Pregunta

Estoy escribiendo una utilidad para mí, en parte como un ejercicio para aprender C# Reflection y en parte porque realmente quiero la herramienta resultante para mi propio uso.

Lo que busco es básicamente apuntar la aplicación a un ensamblado y elegir una clase determinada desde la cual seleccionar las propiedades que deben incluirse en un formulario HTML exportado como campos.Ese formulario luego se usará en mi aplicación ASP.NET MVC como el comienzo de una Vista.

Como estoy usando objetos Subsonic para las aplicaciones que quiero usar, esto debería ser razonable y pensé que, al querer incluir cosas como HTML de salida diferente según el tipo de datos, Reflection era la forma de hacerlo.

Lo que estoy buscando, sin embargo, parece difícil de alcanzar.Estoy intentando tomar el DLL/EXE elegido a través de OpenFileDialog como punto de partida y cargarlo:

String FilePath = Path.GetDirectoryName(FileName);
System.Reflection.Assembly o = System.Reflection.Assembly.LoadFile(FileName);

Eso funciona bien, pero debido a que los objetos generados por Subsonic en realidad están llenos de tipos de objetos definidos en Subsonic.dll, etc., esos objetos dependientes no se cargan.Ingresar:

AssemblyName[] ReferencedAssemblies = o.GetReferencedAssemblies();

Eso también contiene exactamente lo que yo esperaría.Sin embargo, lo que estoy tratando de descubrir es cómo cargar esos ensamblajes para que la excavación en mis objetos funcione correctamente.Entiendo que si esos ensamblados estuvieran en el GAC o en el directorio del ejecutable en ejecución, podría simplemente cargarlos por su nombre, pero no es probable que ese sea el caso para este caso de uso y es mi caso de uso principal.

Entonces, todo se reduce a cómo cargo un ensamblaje determinado y todos sus ensamblajes arbitrarios comenzando con un nombre de archivo y dando como resultado un árbol de tipos, propiedades, métodos, etc. completamente navegable por Reflection.

Sé que herramientas como Reflector hacen esto, simplemente no puedo encontrar la sintaxis para hacerlo.

¿Fue útil?

Solución

Un par de opciones aquí:

  1. Adjuntar a AppDomain.AssemblyResolve y hacer otro LoadFile en base al montaje solicitado.
  2. Gira otro AppDomain con el directorio como base y cargar los ensamblados en ese AppDomain.

Recomiendo encarecidamente seguir la opción 2, ya que probablemente será más limpia y le permitirá descargar todos esos ensamblajes después.Además, considere cargar ensamblajes en el contexto de solo reflexión si solo necesita reflexionar sobre ellos (consulte Assembly.ReflectionOnlyLoad).

Otros consejos

Me ejercite Kent BoogaartLa segunda opción.Básicamente tuve que:

1.) Implementar el ResolveEventHandler en una clase separada, heredando de MarshalByRefObject y agregando el Serializable atributo.

2.) Agregar el actual ApplicationBase, esencialmente donde está el dll del controlador de eventos, al AppDomain PrivateBinPath.

Puedes encontrar el código en github.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top