begin process at 2010 02 10 11:39:10
  Trouver un code source :
 
dans
 
Accueil > 

Code

 > 

.NET

 > PLUGIN PROGRAMME EXTENSIBLE GRÂCE AUX MODULES

PLUGIN PROGRAMME EXTENSIBLE GRÂCE AUX MODULES


 Information sur la source

Note :
9,25 / 10 - par 4 personnes
9,25 / 10

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10
Catégorie :.NET Source .NET ( DotNet ) Classé sous :plugin, reflection, latebinding, attribute, assembly Niveau :Expert Date de création :08/06/2006 Vu / téléchargé :8 524 / 806

Auteur : badrbadr

Ecrire un message privé
Site perso
Commentaire sur cette source (5)
Ajouter un commentaire et/ou une note

 Description

Cliquez pour voir la capture en taille normale
Bonjour,
Ce programme vous permet de charger des modules d'une manière dynamique. Ces modules doivent impérativement implémenter l’interface IFormAddOn ou IMenuAddOn afin d’être charger correctement (voir CommonTypes pour plus de détails).
Trois modules sont fournis pour les tests :
· AboutMenuItem
· FontToolBar
· LeftToolBar
Avant le chargement d’un module, le programme récupère les informations sur celui-ci. Les informations sont stockées dans chaque assembly (.dll) sous forme d’attribut personalisé (voir ModuleInfoAttribute dans CommonTypes pour plus de détails).
Le but de ce programme est de montrer comment on peut réaliser des applications qui peuvent "grandir".

Source

  • using System;
  • using System.Windows.Forms;
  • using System.IO;
  • using System.Reflection;
  • using CommonTypes;
  • namespace PlugIn
  • {
  • class AssemblyLoader
  • {
  • #region Variables
  • //message d'erreur
  • private string errorMessage = null;
  • //référence vers la fenêtre principale
  • private Form form = null;
  • //référence vers le menu de la fenêtre principale
  • private MenuStrip menuStrip = null;
  • //assembly qui va être charger plus tard
  • private Assembly asm = null;
  • //information sur l'assembly
  • private ModuleInfoAttribute moduleInfo = null;
  • #endregion
  • #region Constructeur
  • public AssemblyLoader(Form form, MenuStrip menuStrip)
  • {
  • this.form = form;
  • this.menuStrip = menuStrip;
  • }
  • #endregion
  • #region Load
  • public bool Load(string filepath)
  • {
  • //on vérifie que l'assembly à charger existe
  • if (!File.Exists(filepath))
  • {
  • errorMessage = "Le fichier n'existe pas.";
  • return false;
  • }
  • //on charge l'assemby en prenant soin de s'assurer qu'elle est valide avec un try catch
  • try
  • {
  • asm = Assembly.LoadFrom(filepath);
  • }
  • catch
  • {
  • errorMessage = "Le fichier assembly est corrompu. Le fichier doit être une dll .net afin d'être chargé correctement.";
  • return false;
  • }
  • //on récupère tous les types contenus dans l'assembly
  • //type = class, enum, interface, delegate et struct
  • Type[] types = asm.GetTypes();
  • //on extrait l'info de l'assembly en récupérant l'attribut ModuleInfo
  • ExtractInfo();
  • //on demande à l'utilisateur s'il veut charger le module
  • if (moduleInfo == null)
  • {
  • if (MessageBox.Show("On ne dispose d'aucune information sur ce module. Voulez-vous continuer le chargement ?", "Aucune Information", MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation) == DialogResult.No)
  • return false;
  • }
  • else
  • {
  • ModuleInfoForm moduleInfoForm = new ModuleInfoForm();
  • moduleInfoForm.setInfo(moduleInfo);
  • if (moduleInfoForm.ShowDialog() == DialogResult.No) return false;
  • }
  • //ce booléan nous informe si oui ou non on a trouvé au moins une classe qui implèmente
  • //l'interface IFormAddOn ou IMenuAddOn
  • bool foundInterface = false;
  • for (int i = 0; i < types.Length; i++)
  • {
  • Type IFormAddOnType = types[i].GetInterface("IFormAddOn");
  • Type IMenuAddOnType = types[i].GetInterface("IMenuAddOn");
  • //si notre type (une classe ici) implémente l'une de ces deux interfaces alosr...
  • if (IFormAddOnType != null)
  • {
  • //1 - instancier la classe
  • object o = asm.CreateInstance(types[i].FullName);
  • IFormAddOn formAddOn = o as IFormAddOn;
  • //2 - invoker la méthode d'installation
  • formAddOn.Install(form);
  • foundInterface = true;
  • }
  • if (IMenuAddOnType != null)
  • {
  • //1 - instancier la classe
  • object o = asm.CreateInstance(types[i].FullName);
  • IMenuAddOn menuAddOn = o as IMenuAddOn;
  • //2 - invoker la méthode d'installation
  • menuAddOn.Install(menuStrip);
  • foundInterface = true;
  • }
  • }
  • if (foundInterface)
  • {
  • return true;
  • }
  • else
  • {
  • errorMessage = "L'assemby spécifié ne contient aucun module.";
  • return false;
  • }
  • }
  • #endregion
  • #region ExtractInfo
  • private void ExtractInfo()
  • {
  • object[] moduleInfoArray = asm.GetCustomAttributes(typeof(ModuleInfoAttribute), false);
  • if (moduleInfoArray.Length != 0) moduleInfo = (ModuleInfoAttribute)moduleInfoArray[0];
  • }
  • #endregion
  • #region GetErrorMessage
  • public string GetErrorMessage() { return errorMessage; }
  • #endregion
  • }
  • }
using System;
using System.Windows.Forms;
using System.IO;
using System.Reflection;
using CommonTypes;

namespace PlugIn
{
    class AssemblyLoader
    {
        #region Variables
        //message d'erreur
        private string errorMessage = null;
        //référence vers la fenêtre principale
        private Form form = null;
        //référence vers le menu de la fenêtre principale
        private MenuStrip menuStrip = null;
        //assembly qui va être charger plus tard
        private Assembly asm = null;
        //information sur l'assembly
        private ModuleInfoAttribute moduleInfo = null;
        #endregion

        #region Constructeur
        public AssemblyLoader(Form form, MenuStrip menuStrip)
        {
            this.form = form;
            this.menuStrip = menuStrip;
        }
        #endregion
        #region Load
        public bool Load(string filepath)
        {
            //on vérifie que l'assembly à charger existe
            if (!File.Exists(filepath))
            {
                errorMessage = "Le fichier n'existe pas.";
                return false;
            }
            //on charge l'assemby en prenant soin de s'assurer qu'elle est valide avec un try catch
            try
            {
                asm = Assembly.LoadFrom(filepath);
            }
            catch
            {
                errorMessage = "Le fichier assembly est corrompu. Le fichier doit être une dll .net afin d'être chargé correctement.";
                return false;
            }
            //on récupère tous les types contenus dans l'assembly
            //type = class, enum, interface, delegate et struct
            Type[] types = asm.GetTypes();
            //on extrait l'info de l'assembly en récupérant l'attribut ModuleInfo
            ExtractInfo();
            //on demande à l'utilisateur s'il veut charger le module
            if (moduleInfo == null)
            {
                if (MessageBox.Show("On ne dispose d'aucune information sur ce module. Voulez-vous continuer le chargement ?", "Aucune Information", MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation) == DialogResult.No)
                    return false;
            }
            else
            {
                ModuleInfoForm moduleInfoForm = new ModuleInfoForm();
                moduleInfoForm.setInfo(moduleInfo);
                if (moduleInfoForm.ShowDialog() == DialogResult.No) return false;
            }
            //ce booléan nous informe si oui ou non on a trouvé au moins une classe qui implèmente
            //l'interface IFormAddOn ou IMenuAddOn
            bool foundInterface = false;
            for (int i = 0; i < types.Length; i++)
            {
                Type IFormAddOnType = types[i].GetInterface("IFormAddOn");
                Type IMenuAddOnType = types[i].GetInterface("IMenuAddOn");
                //si notre type (une classe ici) implémente l'une de ces deux interfaces alosr...
                if (IFormAddOnType != null)
                {
                    //1 - instancier la classe
                    object o = asm.CreateInstance(types[i].FullName);
                    IFormAddOn formAddOn = o as IFormAddOn;
                    //2 - invoker la méthode d'installation
                    formAddOn.Install(form);
                    foundInterface = true;
                }
                if (IMenuAddOnType != null)
                {
                    //1 - instancier la classe
                    object o = asm.CreateInstance(types[i].FullName);
                    IMenuAddOn menuAddOn = o as IMenuAddOn;
                    //2 - invoker la méthode d'installation
                    menuAddOn.Install(menuStrip);
                    foundInterface = true;
                }
            }
            if (foundInterface)
            {
                return true;
            }
            else
            {
                errorMessage = "L'assemby spécifié ne contient aucun module.";
                return false;
            }

        }
        #endregion
        #region ExtractInfo
        private void ExtractInfo()
        {
            object[] moduleInfoArray = asm.GetCustomAttributes(typeof(ModuleInfoAttribute), false);
            if (moduleInfoArray.Length != 0) moduleInfo = (ModuleInfoAttribute)moduleInfoArray[0];
        }
        #endregion
        #region GetErrorMessage
        public string GetErrorMessage() { return errorMessage; } 
        #endregion
    }
}

 Conclusion

Ma source :
Pro C# 2005 and the .net 2.0 platform (Chapitre 12)

 Fichier Zip

Les Membres Club peuvent télécharger directement un fichier contenu dans le zip sans télécharger le zip en entier !

Télécharger le zip


 Sources du même auteur

Source avec Zip Source avec une capture Source .NET (Dotnet) RESOURCEBINDER : INJECTER ET EXTRAIRE DES RESSOURCES
Source .NET (Dotnet) CONVERSION ASCII-8 - BINAIRE
Source .NET (Dotnet) SQLMANAGER : FACILITE L'ACCÈS À UNE BASE DE DONNÉE MS SQL
Source avec Zip Source avec une capture Source .NET (Dotnet) CRYPTAGE PRÉDÉFINI ET PERSONNALISÉ GRÂCE À LA COMPILATION DY...
Source avec Zip Source avec une capture Source .NET (Dotnet) PACMAN : ÉDITEUR DE NIVEAU

 Sources de la même categorie

Source avec Zip CHAT SERVER-CLIENT par abderrahmenbilog
Source avec Zip Source avec une capture Source .NET (Dotnet) SIMULATION DE CONSOLE POUR WINDOWS MOBILE par originalcompo
Source avec Zip Source .NET (Dotnet) BASE DE DONNÉES EN XML par DanMor498
Source avec Zip Source avec une capture Source .NET (Dotnet) SIMPLECONV - APPLICATION DE CONVERSION MONÉTAIRE AVEC TAUX E... par Jeffrey_
Source avec Zip Source .NET (Dotnet) TRAITEUR D'IMAGE (MINI) par ycyril

 Sources en rapport avec celle ci

Source .NET (Dotnet) WEBTESTPLUGIN - IGNORER DES URLS LORS D'UN TEST WEB VISUAL S... par jesusonline
Source .NET (Dotnet) COMPILATION ET RÉFLECTION par thiosyiasar
Source avec Zip Source .NET (Dotnet) APPELER UNE MÉTHODE PRIVATE D'UNE CLASSE INTERNAL À PARTIR D... par jesusonline
Source avec Zip Source avec une capture Source .NET (Dotnet) EXPLORATEUR D'ASSEMBLY DANS UN TREEVIEW par thiosyiasar
Source avec une capture Source .NET (Dotnet) PREMIER JOUET AVEC SYSTEM.REFLECTION par TheSaib

Commentaires et avis

Commentaire de nightlord666 le 09/06/2006 13:29:33

Bravo pour ta source que je trouve superbe, bien que j'aurais plutôt utilisé des exceptions à la place de ta variable "errorMessage".

En fait, j'ai trouvé une source assez ressemblante sur ce thème sur http://www.c2i.fr/, qui utilisait la même methode que toi. Simple coincidence ?

Commentaire de badrbadr le 09/06/2006 22:39:20

Non, c'est pas une simple coincidence. simplement le fait qu'il n'y a pas mille moyen de charger une assembly et d'instancier un type en .net mais bien une seule manière.
1 - charger l'assembly (Assembly.LoadFrom)
2 - récupérer tout les types et chercher celui qui implémente la bonne interface
3 - invoker la méthode d'installation
Pour le errorMessage, il est généralement à l'intérieur d'un bloc try catch afin de fournir une explication claire (et en français parce que j'ai .net 2.0 en anglais chez moi).

Commentaire de Zeroc00l le 06/09/2007 02:00:42

Elle est ou la fonction Unload pour decharger une dll,
la changer pendant que le rpogramme tourne,
et la recharger :p ?

Commentaire de pdl le 23/11/2007 10:55:44

Bonjour,

Source très intéressante et qui va dans le sens de ce que je suis occupé de réaliser. J'ai tout de même deux question.

1. Je ne comprends pas, ou ne vois pas où tu définis les informations de chaque module ? J'ai créé un module ToolsMenuItem et je sais pas comment je peux spécifier l'auteur, la description, le language et et le nom. Comment fais-tu pour sauver ces informations dans l'Assembly ?

2. Si je souhaite récupérer de l'information présente dans le module mainForm, ou dans une autre DLL chargée comment est-ce que je peux faire ? Je pose cette question, car j'ai dans l'idée de rendre mon développement très modulaire, c'est à dire un projet (dll) par fonctionnalité, mais je vais certainement très vite avoir besoin d'info se trouvant éventuellement dans une autre dll et donc toute la question se pose de savoir comment récupérer celle-ci.

D'avance un grand merci,

Pierre

Commentaire de badrbadr le 23/11/2007 17:23:30

J'ai utilisé les attributs pour stocker ces infos.
Check les fichiers AssemblyInfo.cs pour voir comment les attributs sont utilisés.
Pour la récupération de ces info, le code est dans AssemblyLoader.cs

Bonne chance.

 Ajouter un commentaire


Discussions en rapport avec ce code source dans le forum

Assembly.GetInterfaces() [ par jusob ] Bonjour, J'ai un programme qui doit charger des DLLs. Ces DLLs impl&#233;mentent l'interface PluginInterface. Programme principal: foreach (Typ Assembly: custom attributes [ par jusob ] Bonjour, j'utilise des custom attributes du genre: [assembly:AssemblyTitle("First plugin")] [assembly:AssemblyCompany("MySelf")] [assembly:Assemb Type, string et reflection [ par bigflo93 ] &nbsp;Salut &#224; tous :)Je suis en pleine reflection en ce moment :) et je cherche &#224; instancier une classe &#224; partir d'une string.Enfin, pl Reflection DLL [ par RM50Man ] Voila le code ou j utilise la reflection pour appeler une m&#233;thode static dans ma DLL Assembly asm = Assembly.LoadFrom("PremiereDLL.dll"); Type[] DLL reflection [ par RM50Man ] Pour utiliser une dll est ce qu on est toujours d utiliser la reflection!!!!RM50man assembly manquante [ par el_teedee ] Salut &#224; tous, nouveau sur C#, je suis d&#233;j&#224; confronter au probl&#232;me suivant lorsque je veux ouvrir un projet existant : j'ai plus Création dll N° assembly... [ par Syruis ] Bonjour, je me suis mis au C# pour faire une dll qui devrait me servir en ASP. Donc pour l'integrer a l'asp &lt;% 'Appel ASP il faut importer le dll Charger un webform a partir d'une dll [ par daevon ] Bonjour,J'ai deja pos&#233; mon probleme dans la partie dotnet mais vu le peu de reactivit&#233; et le peu de temps que je dispose maintenant je repos embedded icon [ par dinytro ] Bonjour, je d&#233;veloppe une palli dans laquelle j'ai ajout&#233; une icone en "embedded resources" (Add-&gt;ExistingItem-&gt;demoDirectory.ico)J'ia Problème de type avec une assembly [ par dinytro ] Bonjour, je souhaiterais r&#233;cup&#233;rer le type d'une assembly que je charge avec la methode SampleAssembly = Assembly.LoadFrom(@pathAssembly); E


Nos sponsors


Sondage...

Comparez les prix

CalendriCode

Février 2010
LMMJVSD
1234567
891011121314
15161718192021
22232425262728

Consulter la suite du CalendriCode

 
Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils.
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés

Google Coop CodeS-SourceS Google Coop CodeS-SourceS
Temps d'éxécution de la page : 1,092 sec (3)

Nous contacter | Annoncer sur CodeS-SourceS | Mentions légales