我正在尝试编写一个插件系统,以为我的应用程序提供某些可扩展性,以便某人可以为该应用程序编写一个或多个插件,而无需接触主应用程序的代码(并且有可能破坏某些内容)。
我已经编写了基本的“ IPlugin”接口(自动柜员机,尚未执行任何操作)
这是我的加载方式:
public static void Load() { // rawr: http://www.codeproject.com/KB/cs/c__plugin_architecture.aspx String[] pluginFiles = Directory.GetFiles(Plugins.PluginsDirectory, "*.dll"); foreach (var plugin in pluginFiles) { Type objType = null; try { //Assembly.GetExecutingAssembly().GetName().Name MessageBox.Show(Directory.GetCurrentDirectory()); Assembly asm = Assembly.Load(plugin); if (asm != null) { objType = asm.GetType(asm.FullName); if (objType != null) { if (typeof(IPlugin).IsAssignableFrom(objType)) { MessageBox.Show(Directory.GetCurrentDirectory()); IPlugin ipi = (IPlugin)Activator.CreateInstance(objType); ipi.Host = Plugins.m_PluginsHost; ipi.Assembly = asm; } } } } catch (Exception e) { MessageBox.Show(e.ToString(), "Unhandled Exception! (Please Report!)", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Information); } } }
一位朋友试图提供帮助,但我真的不明白出了什么问题。
插件的文件夹结构如下:
\ \插件\
所有插件都在[root]目录中引用了一个名为“ Lab.Core.dll”的.dll,并且由于加载了重复的引用,因此它在Plugins目录中不存在。
该插件系统是从Lab.Core.dll加载的,该文件也被我的可执行文件引用。Lab.Core.dll中也包含“ IPlugin”类型。顾名思义,Lab.Core.dll是我的应用程序的核心。
编辑:
问题:为什么/我要得到什么例外,我该如何解决?
最终编辑:
好的,所以我看了一个朋友为TF2调节器编写的源代码后,决定重新编写它。
这是我得到的,它可以正常工作:
public class TestPlugin : IPlugin { #region Constructor public TestPlugin() { // } #endregion #region IPlugin Members public String Name { get { return "Test Plugin"; } } public String Version { get { return "1.0.0"; } } public String Author { get { return "Zack"; } } public Boolean OnLoad() { MessageBox.Show("Loaded!"); return true; } public Boolean OnAllLoaded() { MessageBox.Show("All loaded!"); return true; } #endregion } public static void Load(String file) { if (!File.Exists(file) || !file.EndsWith(".dll", true, null)) return; Assembly asm = null; try { asm = Assembly.LoadFile(file); } catch (Exception) { // unable to load return; } Type pluginInfo = null; try { Type[] types = asm.GetTypes(); Assembly core = AppDomain.CurrentDomain.GetAssemblies().Single(x => x.GetName().Name.Equals("Lab.Core")); Type type = core.GetType("Lab.Core.IPlugin"); foreach (var t in types) if (type.IsAssignableFrom((Type)t)) { pluginInfo = t; break; } if (pluginInfo != null) { Object o = Activator.CreateInstance(pluginInfo); IPlugin plugin = (IPlugin)o; Plugins.Register(plugin); } } catch (Exception) { } } public static void LoadAll() { String[] files = Directory.GetFiles("./Plugins/", "*.dll"); foreach (var s in files) Load(Path.Combine(Environment.CurrentDirectory, s)); for (Int32 i = 0; i < Plugins.List.Count; ++i) { IPlugin p = Plugins.List.ElementAt(i); try { if (!p.OnAllLoaded()) { Plugins.List.RemoveAt(i); --i; } } catch (Exception) { Plugins.List.RemoveAt(i); --i; } } }
听起来您有一个循环参考。您说您的插件引用了Lab.Core.DLL,但是您也说这些插件是从Lab.Core.DLL加载的。
我是不是误会了这里发生的事情?
编辑:确定,现在您已经将问题添加到问题中了…
您需要使Lab.Core.DLL可被加载的插件访问,因为它是依赖项。通常,这意味着将其放在同一目录或GAC中。
我怀疑这里存在更深层次的设计问题,但这是您的直接问题。