begin process at 2012 02 09 19:02:45
  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é :9 843 / 882

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
Avan t 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 Source avec une capture Source .NET (Dotnet) ORIONBANQUE par toutphp
Source avec Zip Source avec une capture Source .NET (Dotnet) ORIONAPPLICATION par toutphp
Source avec Zip SOCKET CONNEXION CLIENT & SERVEUR par ziedto83
Source avec Zip Source .NET (Dotnet) FFMPEG.NET : WRAPPER .NET DE FFMPEG par MasterShadows
Source avec Zip Source .NET (Dotnet) ATTACHER, CRÉER ET SAUVEGARDER UNE BASE DE DONNÉES SQL SERVE... par Alvepinai

 Sources en rapport avec celle ci

Source avec Zip Source .NET (Dotnet) SCRIPTS DE PILOTAGE REFLECTION 8 par Renfield
Source avec Zip PREPAREDFORMAT par Warny
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 Commentaires avec reflection [ par chriskang ] Bonjour, j'utilise les méthodes de System.Reflection pour récupérer les données de certaines classes contenues dans un assembly. En particulier, j'uti Autre question sur la Reflection [ par mcferson ] Bonjour ici. depuis ce code :[code=cs]public void GetDriver(string model) { if (model.Contains("AVL VT-SERIAL")) ereur de (Microsoft.DirectX.AudioVideoPlayback) [ par zimamouche1 ] j'essaie de devloper un lecteur MP3 par c# j'ajoute la réference Microsoft.DirectX.AudioVideoPlayback mais il existe un probléme: __________________ Plugin .Net WPF [ par xmox667 ] Salut à tous, J'essaye de rendre modulaire une application WPF. Dans un assembly externe j'ai une classe et un datatemplate. Dans l'application hôt Problème de FileLoadException en chargeant un assembly [ par Hermios ] Salut à tous, Je développe sous Visual C# 2010 express, et mon projet consiste entre autre à créer un exécutable pour charger un fichier dll, via Asse Problème pour charger une assembly externe, sans copie locale [ par Hermios ] Salut à tous, J'ai crée une dll avec une config, et souhaiterait l'importer dans un nouveau projet. J'ai donc ajouté une référence à cette dll dans mo Probleme assembly [ par Aposia ] J'ai une assembly qui fonctionne tres bien en local sur une application. L'importation se fait sans probleme. Cependant, je veux maintenant utiliser c Creation d'un plugin IE [ par LAlex ] Salut TLM !Je suis en train d'effectuer le portage d'une application Client/Serveur en n-Tiers pour le Web. L'application existante génère un document


Nos sponsors


Sondage...

CalendriCode

Février 2012
LMMJVSD
  12345
6789101112
13141516171819
20212223242526
272829    

Consulter la suite du CalendriCode

Photothèque

 
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 : 6,178 sec (4)

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