题
我想写一个插件系统提供一些可扩展性,以我的应用程序,以便有人能写的应用程序插件(S)不接触的主要应用程序的代码(和风险打破东西)。
我已经得到了基地 “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);
}
}
}
有一个朋友试图帮助,但我真的不明白发生了什么事。
有插件的文件夹结构如下:
\结果 \插件\结果
所有的插件引用在[根]目录中称为“Lab.Core.dll” .dll和它不存在,因为被装入的重复引用的插件目录。
在插件系统从Lab.Core.dll其也由我的可执行文件引用,加载。键入“IPlugin”是Lab.Core.dll为好。 Lab.Core.dll是,正如命名,芯我的应用程序的
修改强>
问:为什么?/什么是例外,我得到,我怎么可能去修复它。
<强> FINAL编辑:强>
好了,所以我决定去寻找一些源代码,一个朋友写的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
我怀疑有在这里打球更深层次的设计问题,但这是立即解决问题。
其他提示
在托管扩展框架(MEF)是在.NET一个新的库,它使应用程序和组件更好的重用。使用MEF,.NET应用程序可以被静态编译,动态组成的转变。如果您正在构建扩展的应用程序,可扩展的框架和应用扩展,那么MEF是你。
http://www.codeplex.com/MEF 秒>
编辑:CodePlex上会消失 - 的代码已被移动到Github的用于存档目的仅: https://开头github.com/MicrosoftArchive/mef
作为一个方面答复,我使用这些2个接口用于实现
///<summary>
///</summary>
public interface IPlugin {
///<summary>
///</summary>
string Name { get; }
///<summary>
///</summary>
string Description { get; }
///<summary>
///</summary>
string Author { get; }
///<summary>
///</summary>
string Version { get; }
///<summary>
///</summary>
IPluginHost Host { get; set; }
///<summary>
///</summary>
void Init();
///<summary>
///</summary>
void Unload();
///<summary>
///</summary>
///<returns></returns>
IDictionary<int, string> GetOptions();
///<summary>
///</summary>
///<param name="opcion"></param>
void ExecuteOption(int option);
}
///<summary>
///</summary>
public interface IPluginHost {
///<summary>
///</summary>
IDictionary<string, object> Variables { get; }
///<summary>
///</summary>
///<param name="plugin"></param>
void Register(IPlugin plugin);
}