Posso carregar um assembly .NET em tempo de execução e instanciar um tipo sabendo apenas o nome?

É possível instanciar um object em tempo de execução se eu tiver apenas o nome da DLL e o nome da class, sem adicionar uma referência ao assembly no projeto? A class implementa uma interface, então, uma vez que eu instancie a class, eu a colocarei na interface.

Nome da assembly:

library.dll

Digite o nome:

Company.Project.Classname


EDIT: Eu não tenho o caminho absoluto da DLL, então Assembly.LoadFile não funcionará. A DLL pode estar na raiz do aplicativo, system32 ou até mesmo carregada no GAC.

Sim. Você precisa usar Assembly.LoadFrom para carregar o assembly na memory, então você pode usar Activator.CreateInstance para criar uma instância do seu tipo preferido. Você precisará procurar o tipo primeiro usando a reflection. Aqui está um exemplo simples:

 Assembly assembly = Assembly.LoadFrom("MyNice.dll"); Type type = assembly.GetType("MyType"); object instanceOfMyType = Activator.CreateInstance(type); 

Atualizar

Quando você tem o nome do arquivo de assembly eo nome do tipo, você pode usar Activator.CreateInstance(assemblyName, typeName) para solicitar a resolução do tipo .NET para resolver isso em um tipo. Você poderia envolver isso com um try / catch para que, se ele falhar, você possa executar uma pesquisa de diretórios onde você pode armazenar especificamente assemblies adicionais que, de outra forma, poderiam não ser pesquisados. Isso usaria o método anterior nesse ponto.

Considere as limitações dos diferentes methods Load* . Dos documentos do MSDN …

LoadFile não carrega arquivos no contexto LoadFrom e não resolve dependencies usando o caminho de carga, como o método LoadFrom faz.

Mais informações sobre contextos de carga podem ser encontradas nos documentos do LoadFrom .

Activator.CreateInstance deveria funcionar.

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

Nota: O nome do tipo deve ser o tipo completo.

Exemplo:

 var aray = (IList)Activator.CreateInstance("mscorlib","System.Collections.ArrayList").Unwrap(); aray.Add(10); foreach (object obj in aray) { Console.WriteLine(obj); } 

Eu encontrei esta pergunta e algumas respostas muito úteis, no entanto eu tive problemas de caminho, por isso esta resposta iria cobrir biblioteca de carregamento, encontrando o caminho do diretório bin.

Primeira solução:

 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 solução

 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"); 

Você pode usar o mesmo princípio para interfaces (você criaria uma class, mas lançaria para interface), como:

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

Este exemplo é para aplicativo da web, mas semelhante pode ser usado para o aplicativo Desktop, somente o caminho é resolvido de maneira diferente, por exemplo

 Path.GetDirectoryName(Application.ExecutablePath) 

Sim. Eu não tenho nenhum exemplo que eu tenha pessoalmente disponível agora. Eu vou postar depois quando eu encontrar alguns. Basicamente você vai usar reflexo para carregar a assembly e, em seguida, para puxar os tipos que você precisa para isso.

Enquanto isso, este link deve começar:

Usando a reflection para carregar assemblies não referenciados em tempo de execução

 ((ISomeInterface)Activator.CreateInstance(Assembly.LoadFile("somePath").GetTypes()[0])).SomeInterfaceMethod(); 

Você pode carregar uma assembly usando os methods * Assembly.Load **. Usando Activator.CreateInstance você pode criar novas instâncias do tipo que você deseja. Tenha em mente que você precisa usar o nome completo do tipo da class que deseja carregar (por exemplo, Namespace.SubNamespace.ClassName ). Usando o método InvokeMember da class Type, você pode invocar methods no tipo.

Além disso, leve em consideração que uma vez carregado, um assembly não pode ser descarregado até que todo o AppDomain seja descarregado também (isso é basicamente um memory leaks).

Dependendo de como este tipo de funcionalidade é intrínseca ao seu projeto, você pode querer considerar algo como o MEF, que cuidará do carregamento e da junit de componentes para você.

A partir do Framework v4.5, você pode usar Activator.CreateInstanceFrom () para instanciar facilmente classs dentro de assemblies. O exemplo a seguir mostra como usá-lo e como chamar um método passando parâmetros e obtendo o valor de retorno.

  // Assuming moduleFileName contains full or valid relative path to assembly var moduleInstance = Activator.CreateInstanceFrom(moduleFileName, "MyNamespace.MyClass"); MethodInfo mi = moduleInstance.Unwrap().GetType().GetMethod("MyMethod"); // Assuming the method returns a boolean and accepts a single string parameter bool rc = Convert.ToBoolean(mi.Invoke(moduleInstance.Unwrap(), new object[] { "MyParamValue" } )); 

É fácil.

Exemplo do MSDN:

 public static void Main() { // Use the file name to load the assembly into the current // application domain. Assembly a = Assembly.Load("example"); // Get the type to use. Type myType = a.GetType("Example"); // Get the method to call. MethodInfo myMethod = myType.GetMethod("MethodA"); // Create an instance. object obj = Activator.CreateInstance(myType); // Execute the method. myMethod.Invoke(obj, null); } 

Aqui está um link de referência

https://msdn.microsoft.com/pt-br/library/25y1ya39.aspx

Sim, é, você desejará usar o método Load estático na class Assembly e, em seguida, chamar, em seguida, chamar o método CreateInstance na instância do Assembly retornada para você da chamada para Load.

Além disso, você pode chamar um dos outros methods estáticos começando com “Load” na class Assembly, dependendo de suas necessidades.

 Assembly assembly = Assembly.LoadFrom("MyAssembly.dll"); Type type = assembly.GetType("MyType"); dynamic instanceOfMyType = Activator.CreateInstance(type); 

Assim, desta forma você pode usar funções não com get methodinfo e, em seguida, invocá-lo.Você vai fazer como esta instanceOfMyType.MethodName (); Mas você não pode usar Intellisense porque tipos dynamics são typescripts em tempo de execução, não em tempo de compilation.

Você pode fazer isso da seguinte maneira:

 using System.Reflection; Assembly MyDALL = Assembly.Load("DALL"); //DALL name of your assembly Type MyLoadClass = MyDALL.GetType("DALL.LoadClass"); // name of your class object obj = Activator.CreateInstance(MyLoadClass);