Как я могу передать аргумент подключаемому модулю C #, загружаемому через Assembly.CreateInstance?
-
02-07-2019 - |
Вопрос
То, что у меня есть сейчас (который успешно загружает плагин), это:
Assembly myDLL = Assembly.LoadFrom("my.dll");
IMyClass myPluginObject = myDLL.CreateInstance("MyCorp.IMyClass") as IMyClass;
Это работает только для класса, у которого есть конструктор без аргументов.Как мне передать аргумент конструктору?
Решение
Ты не можешь.Вместо этого используйте Активатор.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());
}
}
}
}
Другие советы
звонить
public object CreateInstance(string typeName, bool ignoreCase, BindingFlags bindingAttr, Binder binder, object[] args, CultureInfo culture, object[] activationAttributes)
вместо этого.Документы MSDN
Редактировать:Если вы собираетесь проголосовать против этого, пожалуйста, объясните, почему такой подход неправильный / или не самый лучший.
Вы можете с помощью Активатор.CreateInstance
Activator.CreateInstance принимает тип и все, что вы хотите передать конструктору типов.
http://msdn.microsoft.com/en-us/library/system.activator.createinstance.aspx
Вы также можете не использовать Activator.CreateInstance, который мог бы работать лучше.Смотрите ниже вопрос StackOverflow.
Как передать аргументы ctor в Activator.CreateInstance или использовать IL?