Como posso passar um argumento para um C # plug-in a ser carregado através Assembly.CreateInstance?

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

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?

Foi útil?

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

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?

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top