Domanda

Sto cercando di scrivere un sistema di plugin per fornire una certa estensibilità a un'applicazione di mine in modo che qualcuno possa scrivere un plugin (s) per l'applicazione senza toccare il codice dell'applicazione principale (e il rischio di rompere qualcosa).

Ho la base "IPlugin" interfaccia scritta (atm, nulla è ancora implementata)

Ecco come sto caricando:

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 amico ha cercato di aiutare, ma io davvero non ha capito cosa non andava.

La struttura delle cartelle per i plugin è la seguente:

\
\ Plugins \

Tutti i plugin riferimento a una DLL chiamata "Lab.Core.dll" nella directory [root] e non è presente nella directory dei plugin a causa di riferimenti duplicati corso di caricamento.

Il sistema di plugin viene caricato dal Lab.Core.dll, che fa riferimento anche dal mio eseguibile. Tipo "IPlugin" è in Lab.Core.dll pure. Lab.Core.dll è, esattamente come il nome, il nucleo della mia applicazione.

Modifica

Domanda: Perché / Che cosa è che fa eccezione sto ottenendo e come potrei fare per risolverlo

Modifica FINALE:

Ok, quindi ho deciso di ri-scriverlo dopo aver guardato un po 'di codice sorgente di un amico ha scritto per un regolatore di TF2.

Ecco quello che ho ottenuto e funziona:

    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;
            }
        }
    }
È stato utile?

Soluzione

Sembra che si dispone di un riferimento circolare. Hai detto che il tuo plugin riferimento Lab.Core.DLL, ma si dicono anche i plugin vengono caricati dal Lab.Core.DLL.

Perchè sono incomprensioni che cosa sta accadendo qui?

EDIT: OK, ora che avete aggiunto la tua domanda alla domanda ...

È necessario avere Lab.Core.DLL accessibili al plugin viene caricato dal momento che è una dipendenza. Normalmente ciò significherebbe averlo nella stessa directory o in GAC.

Ho il sospetto che ci sono problemi di progettazione più profonde in gioco qui, ma questo è il tuo problema immediato.

Altri suggerimenti

  

L'Extensibility Framework Managed (MEF) è una nuova libreria in .NET che consente una maggiore riutilizzo di applicazioni e componenti. Utilizzando MEF, NET possono rendere il passaggio dalla fase di compilazione staticamente composta dinamicamente. Se si sta creando applicazioni estendibili, framework estensibile ed estensioni applicative, allora MEF è per voi.

http://www.codeplex.com/MEF

Modifica: CodePlex sta andando via - il codice è stato spostato a Github per scopi di archiviazione solo: https: // github.com/MicrosoftArchive/mef

Come risposta laterale, io uso questi 2 interfacce di applicazione che

///<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);
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top