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 / Exemple :
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)
Vous n'êtes pas encore membre ?
inscrivez-vous, c'est gratuit et ça prend moins d'une minute !
Les membres obtiennent plus de réponses que les utilisateurs anonymes.
Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.
Le fait d'être membre vous permet d'avoir des options supplémentaires.