Come posso passare un argomento a un plug-in C # che viene caricato tramite Assembly.CreateInstance?

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

Domanda

Quello che ho ora (che carica correttamente il plug-in) è questo:

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

Funziona solo per una classe che ha un costruttore senza argomenti. Come posso passare un argomento a un costruttore?

È stato utile?

Soluzione

Non puoi. Utilizza invece Activator.CreateInstance come mostrato nell'esempio seguente (nota che il Lo spazio dei nomi client si trova in una DLL e l'host in un'altra. Entrambi devono essere trovati nella stessa directory affinché il codice funzioni.)

Tuttavia, se vuoi creare un'interfaccia veramente collegabile, ti suggerisco di usare un metodo Initialize che accetta i parametri dati nella tua interfaccia, invece di fare affidamento su costruttori. In questo modo puoi semplicemente richiedere che la classe di plugin implementi la tua interfaccia, invece di " sperando " che accetta i parametri accettati nel costruttore.

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

Altri suggerimenti

chiamata

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

, invece. Documenti MSDN

MODIFICA: se hai intenzione di votare questo verso il basso, ti preghiamo di capire perché questo approccio è sbagliato / o non il modo migliore.

Activator.CreateInstance accetta un tipo e qualunque cosa tu voglia passare al costruttore dei tipi.

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

Non è inoltre possibile utilizzare Activator.CreateInstance, che potrebbe funzionare meglio. Vedi sotto la domanda StackOverflow.

Come passare argomenti ctor in Activator.CreateInstance o usare IL?

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top