¿Cómo puedo pasar un argumento a un complemento de C # que se carga a través de Assembly.CreateInstance?

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

Pregunta

Lo que tengo ahora (que carga correctamente el complemento) es esto:

Assembly myDLL = Assembly.LoadFrom("my.dll");
IMyClass myPluginObject = myDLL.CreateInstance("MyCorp.IMyClass") as IMyClass;

Esto solo funciona para una clase que tiene un constructor sin argumentos. ¿Cómo paso un argumento a un constructor?

¿Fue útil?

Solución

No puedes. En su lugar, use Activator.CreateInstance como se muestra en el siguiente ejemplo (tenga en cuenta que El espacio de nombres del cliente está en una DLL y el Host en otra. Ambos deben encontrarse en el mismo directorio para que funcione el código.)

Sin embargo, si desea crear una interfaz verdaderamente conectable, le sugiero que utilice un método de Inicialización que tome los parámetros dados en su interfaz, en lugar de confiar en los constructores. De esa manera, simplemente puede exigir que la clase de complemento implemente su interfaz, en lugar de " esperando " que acepta los parámetros aceptados en el constructor.

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());
            }
        }
    }
}

Otros consejos

llamada

public object CreateInstance(string typeName, bool ignoreCase, BindingFlags bindingAttr, Binder binder, object[] args, CultureInfo culture, object[] activationAttributes)

en su lugar. MSDN Docs

EDITAR: Si va a votar esto, explique por qué este enfoque es incorrecto o no de la mejor manera.

Puede hacerlo con Activator.CreateInstance

Activator.CreateInstance toma un Tipo y lo que quieras pasar al constructor de Tipos.

http://msdn.microsoft.com/en -us / library / system.activator.createinstance.aspx

Tampoco puede usar Activator.CreateInstance, que podría funcionar mejor. Vea a continuación la pregunta sobre StackOverflow.

¿Cómo pasar ctor args en Activator.CreateInstance o usar IL?

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