161 votos

¿Puedo cargar un ensamblaje .NET en tiempo de ejecución e instanciar un tipo conociendo sólo el nombre?

¿Es posible instanciar un objeto en tiempo de ejecución si sólo tengo el nombre de la DLL y el nombre de la clase, sin añadir una referencia al ensamblaje en el proyecto? La clase implementa una interfaz, por lo que una vez que instancie la clase, la fundiré a la interfaz.

Nombre de la asamblea:

biblioteca.dll

Nombre del tipo:

Empresa.Proyecto.Nombre de clase


EDITAR: No tengo la ruta absoluta de la DLL, así que Assembly.LoadFile no funcionará. La DLL puede estar en el Root de la aplicación, system32, o incluso cargada en el GAC.

209voto

Jeff Yates Puntos 36725

Sí, hay que utilizar Assembly.LoadFrom para cargar el ensamblaje en la memoria, entonces puede utilizar Activator.CreateInstance para crear una instancia de su tipo preferido. Tendrá que buscar el tipo primero usando la reflexión. He aquí un ejemplo sencillo:

Assembly assembly = Assembly.LoadFrom("MyNice.dll");

Type type = assembly.GetType("MyType");

object instanceOfMyType = Activator.CreateInstance(type);

Actualización

Cuando tenga el nombre del archivo de ensamblaje y el nombre del tipo, puede utilizar Activator.CreateInstance(assemblyName, typeName) para pedir a la resolución de tipos de .NET que lo resuelva en un tipo. Podrías envolver esto con un try/catch para que, si falla, puedas realizar una búsqueda en los directorios en los que puedes almacenar específicamente ensamblados adicionales que de otra manera no podrían ser buscados. Esto utilizaría el método anterior en ese punto.

33voto

Anthony Mastrean Puntos 8582

Considere las limitaciones de los diferentes Load* métodos. De la MSDN docs...

LoadFile no carga archivos en el contexto LoadFrom, y no resuelve las dependencias utilizando la ruta de carga, como hace el método LoadFrom.

Puede encontrar más información sobre los Contextos de Carga en el LoadFrom docs.

16voto

tvanfosson Puntos 268301

Activator.CreateInstance debería funcionar.

IFace object = (IFace)Activator.CreateInstance( "AssemblyName",
                                                "TypeName" )
                               .Unwrap();

Nota: El nombre del tipo debe ser el tipo completamente calificado.

Ejemplo:

var aray = (IList)Activator.CreateInstance("mscorlib","System.Collections.ArrayList").Unwrap();
aray.Add(10);

foreach (object obj in aray)
{
    Console.WriteLine(obj);
}

5voto

Sofija Puntos 118

Encontré esta pregunta y algunas respuestas muy útiles, sin embargo tuve problemas de ruta, así que esta respuesta cubriría la carga de la biblioteca encontrando la ruta del directorio bin.

Primera solución:

string assemblyName = "library.dll";
string assemblyPath = HttpContext.Current.Server.MapPath("~/bin/" + assemblyName);
Assembly assembly = Assembly.LoadFrom(assemblyPath);
Type T = assembly.GetType("Company.Project.Classname");
Company.Project.Classname instance = (Company.Project.Classname) Activator.CreateInstance(T);

Segunda solución

string assemblyName = "library.dll";
string assemblyPath = HttpContext.Current.Server.MapPath("~/bin/" + assemblyName);
Assembly assembly = Assembly.LoadFile(assemblyPath);
(Company.Project.Classname) instance = (Company.Project.Classname) assembly.CreateInstance("Company.Project.Classname");

Puedes utilizar el mismo principio para las interfaces (estarías creando una clase pero haciendo un casting a la interfaz), como por ejemplo

(Company.Project.Interfacename) instance = (Company.Project.Interfacename) assembly.CreateInstance("Company.Project.Classname");

Este ejemplo es para una aplicación web, pero podría utilizarse de forma similar para una aplicación de escritorio, sólo que la ruta se resuelve de forma diferente, por ejemplo

Path.GetDirectoryName(Application.ExecutablePath)

2voto

Giovanni Galbo Puntos 8139

Sí. No tengo ningún ejemplo que haya hecho personalmente disponible en este momento. Lo publicaré más tarde cuando encuentre alguno. Básicamente usarás reflection para cargar el ensamblaje y luego para sacar los tipos que necesites para él.

Mientras tanto, este enlace debería servirle para empezar:

Uso de la reflexión para cargar ensamblajes no referenciados en tiempo de ejecución

Iteramos.com

Iteramos es una comunidad de desarrolladores que busca expandir el conocimiento de la programación mas allá del inglés.
Tenemos una gran cantidad de contenido, y también puedes hacer tus propias preguntas o resolver las de los demás.

Powered by:

X