Estoy tratando de escribir un sistema de complemento para proporcionar algo de extensibilidad a una aplicación mía para que alguien pueda escribir un plugin para la aplicación sin tocar el código de la aplicación principal (y arriesgarse a romper algo).Escribiendo el sistema de complemento C#
Tengo la base "IPlugin" interfaz escrita (atm, nada se ha implementado todavía)
Así es como estoy de carga:
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);
}
}
}
Un amigo trató de ayudar pero realmente no entendí lo que estaba mal.
La estructura de carpetas para los plugins es la siguiente:
\
\ Plugins \
Referencia Todos los plugins un .dll denominado "Lab.Core.dll" en el directorio [root] y no está presente en el directorio de complementos debido a la carga de referencias duplicadas.
El sistema de complemento se carga desde Lab.Core.dll al que también hace referencia mi ejecutable. Escriba "IPlugin" también en Lab.Core.dll. Lab.Core.dll es, exactamente como el nombre, el núcleo de mi aplicación.
EDIT:
Pregunta: ¿Por qué/¿Qué es esa excepción que estoy recibiendo y cómo podría ir sobre la fijación él?
edición final:
Ok, así que decidí volver a escribir después de ver algo de código fuente de un amigo escribió para un regulador de TF2.
Aquí es lo que tengo y funciona:
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;
}
}
}
observo que usted no ha hecho una pregunta, que ha acaba de describir lo que estás tratando de hacer. ¿Podría formular su pregunta en forma de pregunta? –
Err. Lo siento, me quedé colgado tratando de explicar lo que estaba haciendo, pero olvidé la pregunta. : x Haré esa edición. – Zack
Por favor, publique la excepción completa que recibió, completa con el seguimiento de la pila y cualquier excepción interna. Publique los resultados de ex.ToString(). –