Как я могу передать аргумент плагину C #, загружаемому через Assembly.CreateInstance? - PullRequest
5 голосов
/ 25 сентября 2008

Что у меня сейчас (что успешно загружает плагин) это:

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

Это работает только для класса, у которого есть конструктор без аргументов. Как передать аргумент конструктору?

Ответы [ 5 ]

12 голосов
/ 25 сентября 2008

Вы не можете. Вместо этого используйте Activator.CreateInstance , как показано в примере ниже (обратите внимание, что пространство имен клиента находится в одной DLL, а хост - в другой. Обе должны быть найдены в одном каталоге для работы кода).

Однако, если вы хотите создать действительно подключаемый интерфейс, я предлагаю вам использовать метод Initialize, который принимает заданные параметры в вашем интерфейсе, вместо того, чтобы полагаться на конструкторы. Таким образом, вы можете просто потребовать, чтобы класс плагина реализовал ваш интерфейс, вместо того, чтобы «надеяться», что он примет принятые параметры в конструкторе.

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());
            }
        }
    }
}
3 голосов
/ 25 сентября 2008

звонок

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

вместо этого. Документы MSDN

РЕДАКТИРОВАТЬ: Если вы собираетесь проголосовать за это, пожалуйста, дайте понять, почему этот подход является неправильным / или не лучшим способом.

2 голосов
/ 25 сентября 2008

Вы можете с помощью Activator.CreateInstance

1 голос
/ 25 сентября 2008

Activator.CreateInstance принимает тип и все, что вы хотите передать конструктору типов.

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

0 голосов
/ 17 июня 2010

Вы также не можете использовать Activator.CreateInstance, который мог бы работать лучше. См. Ниже вопрос StackOverflow.

Как передать аргументы ctor в Activator.CreateInstance или использовать IL?

...