我现在拥有的(成功加载插件)是这样的:
Assembly myDLL = Assembly.LoadFrom("my.dll");
IMyClass myPluginObject = myDLL.CreateInstance("MyCorp.IMyClass") as IMyClass;
这仅适用于具有不带参数的构造函数的类。如何将参数传递给构造函数?
我现在拥有的(成功加载插件)是这样的:
Assembly myDLL = Assembly.LoadFrom("my.dll");
IMyClass myPluginObject = myDLL.CreateInstance("MyCorp.IMyClass") as IMyClass;
这仅适用于具有不带参数的构造函数的类。如何将参数传递给构造函数?
你不能。而是使用Activator.CreateInstance,如下例所示(请注意,客户端命名空间位于一个 DLL 中,而主机位于另一个 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 文档
编辑:如果您要对此投反对票,请深入了解为什么这种方法是错误的/或不是最好的方法。
Activator.CreateInstance 接受一个 Type 和任何你想传递给 Types 构造函数的东西。
http://msdn.microsoft.com/en-us/library/system.activator.createinstance.aspx
您也可以不使用 Activator.CreateInstance,它可以执行得更好。请参阅下面的 StackOverflow 问题。