【发布时间】:2010-11-07 10:23:42
【问题描述】:
我正在尝试编写一个插件系统,以便为我的应用程序提供一些可扩展性,以便有人可以为该应用程序编写插件,而无需接触主应用程序的代码(并冒着破坏某些东西的风险)。
我已经编写了基本的“IPlugin”接口(atm,尚未实现)
这是我的加载方式:
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 加载的,我的可执行文件也引用了它。类型“IPlugin”也在 Lab.Core.dll 中。 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;
}
}
}
【问题讨论】:
-
我注意到您实际上并没有提出问题,您只是描述了您要做什么。你能用问题的形式表达你的问题吗?
-
错误。抱歉,挂断了电话,试图解释我在做什么,但忘记了问题。 :x 我会做那个编辑。
-
请发布您收到的完整异常,包括堆栈跟踪和任何内部异常。发布 ex.ToString() 的结果。
-
asm.GetType(asm.FullName)是什么原因?失败时 asm.FullName 的值是多少?
-
扎克,在下面查看我的答案。为了证明这一点,请将您的插件目录配置为与可执行文件和其他 DLL 相同的目录。
标签: c# plugins extensibility