Question

Je suis en train d'écrire un système de plug-in pour fournir une extensibilité à une application de la mine pour que quelqu'un puisse écrire un plug-in (s) pour l'application sans toucher le code de l'application principale (et casser quelque chose risque).

J'ai la base l'interface écrite "IPlugin" (atm, rien est encore mis en œuvre)

Voici comment je charge:

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 ami a essayé d'aider, mais je ne comprenait vraiment pas ce qui était erroné.

La structure de dossiers pour les modules est la suivante:

\
\ Plugins \

Tous les plugins font référence à un .dll appelé « Lab.Core.dll » dans le répertoire [racine] et il n'est pas présent dans le répertoire Plugins en raison des références en double chargés.

Le système de plug-in est chargé à partir Lab.Core.dll qui est également référencé par mon exécutable. Tapez « IPlugin » est en Lab.Core.dll aussi bien. Lab.Core.dll est, exactement comme le nom, le noyau de ma demande.

EDIT:

Question: Pourquoi / Qu'est-ce que je reçois exception et comment pourrais-je prendre pour le corriger

FINAL EDIT:

Ok, donc j'ai décidé de récrire après avoir regardé un code source un ami a écrit pour un régulateur TF2.

Voici ce que je suis arrivé et il fonctionne:

    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;
            }
        }
    }
Était-ce utile?

La solution

Il semble que vous avez une référence circulaire. Vous avez dit que vos plugins de référence Lab.Core.DLL, mais vous dites aussi les plugins sont chargés à partir Lab.Core.DLL.

Suis-je malentendu ce qui se passe ici?

EDIT: OK maintenant que vous avez ajouté votre question à la question ...

Vous devez avoir Lab.Core.DLL accès au plug-in étant chargé, car il est une dépendance. Normalement, cela voudrait dire avoir dans le même répertoire ou dans le GAC.

Je soupçonne qu'il ya des questions plus profondes de conception en jeu ici, mais c'est votre problème immédiat.

Autres conseils

  

Le cadre Extensibilité (MEF) est géré une nouvelle bibliothèque .NET qui permet une plus grande réutilisation des applications et des composants. L'utilisation MEF, applications .NET peuvent faire le changement d'être compilé statiquement à composé dynamiquement. Si vous construisez des applications extensibles, des cadres extensibles et extensions d'application, puis est pour vous MEF.

http://www.codeplex.com/MEF

Edit: CodePlex va loin - le code a été déplacé vers Github à des fins d'archivage uniquement: https: // github.com/MicrosoftArchive/mef

En réponse côté, j'utiliser ces 2 interfaces pour la mise en œuvre que

///<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);
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top