Pregunta

Estoy tratando de escribir un sistema de plugins para proporcionar cierta extensibilidad a una aplicación de la mina para que alguien pueda escribir un plugin (s) para la aplicación sin tocar el código de la aplicación principal (y el riesgo de romper algo).

Tengo la base "IPlugin" interfaz escrita (atm, nada se ha implementado todavía)

Así es como estoy cargando:

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ía lo que estaba mal.

La estructura de carpetas para los plugins es el siguiente:

\
\ Plugins \

Todos los plugins referencia a una .dll llamado "Lab.Core.dll" en el directorio [root] y que no está presente en el directorio de plugins porque de referencias duplicadas están cargando.

El sistema de plugins se carga desde Lab.Core.dll que también se hace referencia por mi ejecutable. Tipo "IPlugin" está en Lab.Core.dll también. Lab.Core.dll es, exactamente como el nombre, el núcleo de mi solicitud.

EDIT:

Pregunta: ¿Por qué? / ¿Qué es la excepción de que estoy recibiendo y cómo podría ir sobre la fijación que

EDITAR 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.

Esto 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;
            }
        }
    }
¿Fue útil?

Solución

Parece que usted tiene una referencia circular. Usted ha dicho Referencia sus plugins Lab.Core.DLL, pero también dicen que los plugins se cargan desde Lab.Core.DLL.

¿Estoy malentendido lo que está sucediendo aquí?

EDIT: OK ahora que se han añadido a tu pregunta a la pregunta ...

Es necesario tener Lab.Core.DLL accesible para el plugin que se carga, ya que es una dependencia. Normalmente eso significaría tener que en el mismo directorio o en la GAC.

Sospecho que hay profundos problemas de diseño en juego aquí, pero esto es su problema inmediato.

Otros consejos

  

El Marco Extensibilidad Gestionado (MEF) es una nueva biblioteca en .NET que permite una mayor reutilización de aplicaciones y componentes. Usando MEF, aplicaciones .NET pueden hacer el cambio de ser compilado estáticamente a compuesto dinámicamente. Si usted está construyendo aplicaciones extensibles, marcos extensibles y extensiones de aplicación, a continuación, MEF es para ti.

http://www.codeplex.com/MEF

Editar: CodePlex se va - el código ha sido trasladado a Github para propósitos de archivo solamente: https: // github.com/MicrosoftArchive/mef

Como respuesta lado, yo uso estos 2 interfaces de aplicación de dicha

///<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);
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top