Como posso passar um argumento para um C # plug-in a ser carregado através Assembly.CreateInstance?
-
02-07-2019 - |
Pergunta
O que eu tenho agora (que carrega com sucesso o plug-in) é a seguinte:
Assembly myDLL = Assembly.LoadFrom("my.dll");
IMyClass myPluginObject = myDLL.CreateInstance("MyCorp.IMyClass") as IMyClass;
Isso só funciona para uma classe que tem um construtor sem argumentos. Como faço para passar um argumento para um construtor?
Solução
Você não pode. Em vez disso usar Activator.CreateInstance como mostrado no exemplo a seguir (note que o namespace cliente está em um DLL e o anfitrião em outro. Ambos devem ser encontrados no mesmo diretório para o código de trabalho.)
No entanto, se você quiser criar uma interface verdadeiramente pluggable, eu sugiro que você use um método de inicialização que levam os parâmetros dados na sua interface, em vez de depender de construtores. Dessa forma, você pode simplesmente exigir que a classe de plugin implementar sua interface, em vez de "esperança" que aceita os parâmetros aceitos no construtor.
using System;
using Host;
namespace Client
{
public class MyClass : IMyInterface
{
public int _id;
public string _name;
public MyClass(int id,
string name)
{
_id = id;
_name = name;
}
public string GetOutput()
{
return String.Format("{0} - {1}", _id, _name);
}
}
}
namespace Host
{
public interface IMyInterface
{
string GetOutput();
}
}
using System;
using System.Reflection;
namespace Host
{
internal class Program
{
private static void Main()
{
//These two would be read in some configuration
const string dllName = "Client.dll";
const string className = "Client.MyClass";
try
{
Assembly pluginAssembly = Assembly.LoadFrom(dllName);
Type classType = pluginAssembly.GetType(className);
var plugin = (IMyInterface) Activator.CreateInstance(classType,
42, "Adams");
if (plugin == null)
throw new ApplicationException("Plugin not correctly configured");
Console.WriteLine(plugin.GetOutput());
}
catch (Exception e)
{
Console.Error.WriteLine(e.ToString());
}
}
}
}
Outras dicas
chamada
public object CreateInstance(string typeName, bool ignoreCase, BindingFlags bindingAttr, Binder binder, object[] args, CultureInfo culture, object[] activationAttributes)
em seu lugar. MSDN Docs
EDIT:. Se você estiver indo para votar este para baixo, por favor, dar dicas sobre por que esta abordagem é errada / ou não a melhor maneira
Você pode com Activator.CreateInstance
Activator.CreateInstance leva um Tipo e tudo o que você quer passar para o construtor Tipos.
http://msdn.microsoft.com/en -us / library / system.activator.createinstance.aspx
Você também não pode usar Activator.CreateInstance, o que poderia ter um melhor desempenho. Veja abaixo questão StackOverflow.
Como passar args ctor em Activator.CreateInstance ou usar IL?