【发布时间】:2014-02-24 11:07:24
【问题描述】:
我已经开始使用一个简单的插件加载器,它监视一个目录并在其中的 dll 包含 IPlugin 接口时加载插件。
public class PluginLoader : Dictionary<string, IPlugin>
{
private FileSystemWatcher watcher;
private string pluginPath;
public PluginLoader()
: base()
{
pluginPath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "plugins");
if (!Directory.Exists(pluginPath))
Directory.CreateDirectory(pluginPath);
watcher = new FileSystemWatcher(pluginPath, "*.dll");
watcher.IncludeSubdirectories = true;
watcher.Created += watcher_Created;
watcher.EnableRaisingEvents = true;
}
private void watcher_Created(object sender, FileSystemEventArgs e)
{
LoadPlugin(e.FullPath);
}
private void LoadPlugin(string path)
{
IPlugin plugin = null;
Assembly assembly = Assembly.LoadFrom(path);
foreach (Type type in assembly.GetExportedTypes())
{
if (type.IsClass && type.GetInterfaces().Count(iType => iType == typeof(IPlugin)) == 1)
{
ConstructorInfo constructor = type.GetConstructor(new Type[] { });
object instance = constructor.Invoke(new object[] { });
plugin = instance as IPlugin;
// plugin is now not null
}
}
if (plugin != null && !this.ContainsKey(plugin.PluginName))
{
this[plugin.PluginName] = plugin;
}
}
}
此版本的 LoadPlugin() 有效,插件变量最终为 != null。但是,这个不起作用:
private void LoadPlugin(string path)
{
IPlugin plugin = null;
Assembly assembly = Assembly.LoadFrom(path);
foreach (Type type in assembly.GetExportedTypes())
{
if (type.IsClass && type.GetInterface(typeof(IPlugin).FullName) != null)
{
ConstructorInfo constructor = type.GetConstructor(new Type[] { });
object instance = constructor.Invoke(new object[] { });
plugin = instance as IPlugin;
// plugin is still null
}
}
if (plugin != null && !this.ContainsKey(plugin.PluginName))
{
this[plugin.PluginName] = plugin;
}
}
我只是不明白为什么。所以我的问题是:为什么插件在第二个示例中最终为空?
解决方案:
问题是我有两种不同的IPlugin 类型,因为它的组件存在于两个不同的位置。所以删除插件目录下的Framework.Lib.dll就解决了。
【问题讨论】:
-
加载插件成功后,使用
break停止对剩余类型的迭代。
标签: c# .net plugins dll .net-assembly