Accueil > Forum > > > > Creation dynamique d'objet, InvalidCastException
Creation dynamique d'objet, InvalidCastException
dimanche 18 février 2007 à 22:04:32 |
Creation dynamique d'objet, InvalidCastException

Warny
|
Salut, Je cherche à créer un chargeur de classe. Celui-ci doit me permettre de trouver les classes dans une assembly ou un ensemble d'assembly qui dérive d'une classe particulière. Ca, ça marche bien. Ensuite j'essaye d'instancier (grâce à une reflection) ces objets et de les caster dans mon type de base. Et là j'obtient une InvalidCastException. En fait je sèche. Dans ma classe, les procédures importantes sont AddType (qui ajoute un type à la liste des types créables) et Create qui créé une instance d'un type. J'ai une procédure IsBasedOn qui renvoi true si un type dérive d'un autre (par implementation ou interface) et que j'utilise pour valider l'utilisation ou non d'une classe. L'erreur a lieu dans create alors que j'essaye de caster mon objet tout frais sorti du moule. Merci d'avance de votre aide, Olivier Voici les bouts utiles de mon code : class Loader<BaseClass> { privateDictionary<string, Type> creatable; privateType BaseType; privatestring KeyElement; privatestring defaultElement;#region constructeurs///<summary> /// Créé un chargeur de classe ///</summary> public Loader() : this("") { ;}///<summary> /// Créé un chargeur de classes ///</summary> ///<param name="KeyElement">Element servant de clef</param> public Loader(string KeyElement) { this.BaseType = typeof(BaseClass); this.KeyElement = KeyElement; creatable = newDictionary<string,Type>();} #endregion #region gestion des types///<summary> /// Ajoute toutes les classes contenues dans toutes les assemblies d'un répertoire ///</summary> ///<param name="Path">Chemin Contenant les assemblies à charger</param>publicvoid AddFolder(string Path) { //Charge les fichiers contenus dans le répertoire DirectoryInfo directory = newDirectoryInfo(Path); foreach (FileInfo file in directory.GetFiles("*.dll")) {AddAssembly(file.FullName);
} } ///<summary> /// Ajoute toutes les classes contenues dans une assembly ///</summary> ///<param name="Path"></param>publicvoid AddAssembly(string Path) { //Charge l'assembly Assembly assembly = Assembly.LoadFrom(Path); //Récupère tous les type contenus Type[] types = assembly.GetTypes();foreach (Type type in types) {AddType(type);
} } ///<summary> /// Ajoute un type ///</summary> ///<param name="type">Type à ajouter</param> privatevoid AddType(Type type) {
//Vérifie que le type dérive bien de la classe de base if (!IsBasedOn(type,BaseType)) return; // <----- Avec cette procédure, je suis sûr que les types dérivent de BaseClass
//Récupère la valeur clef (nom de la classe si le nom est null) string value; if (KeyElement.Length > 0) {value = type.InvokeMember(KeyElement, BindingFlags.InvokeMethod | BindingFlags.FlattenHierarchy | BindingFlags.GetProperty | BindingFlags.Static | BindingFlags.Public, null, null, null).ToString();} else {value = type.FullName;
} //inscrit la classe dans la listeif (creatable.ContainsKey(value)) {creatable[value] = type;
} else {creatable.Add(value, type);
} } ///<summary> /// Ajoute un type ///</summary> ///<param name="Path">Chemin de l'assembly contenant la classe</param> ///<param name="ClassName">Nom de la classe</param> privatevoid AddType(string Path, string ClassName) { //Charge l'assembly Assembly assembly = Assembly.LoadFrom(Path); //charge le type particulier Type type = assembly.GetType(ClassName); //Ajoute le type AddType(type);} ///<summary> /// Retire un type de la liste ///</summary> ///<param name="Id">Clef du type à enlever</param> publicvoid RemoveType(string Id) {creatable.Remove(Id);
} #endregion #region divers///<summary> /// Défini une classe par défaut si la classe recherchée n'existe pas ///</summary> publicstring DefaultElement { get { return defaultElement; } set { defaultElement = value; }} ///<summary> /// Vérifie si une classe est basée ou dérivée d'un type particulier ///</summary> ///<param name="TestType">Type à tester</param> ///<param name="BaseType">Référence</param> ///<returns></returns> privatebool IsBasedOn(Type TestType, Type BaseType) { if (TestType.IsSubclassOf(BaseType)) returntrue; if (TestType.FullName == BaseType.FullName) returntrue; if (TestType.FullName == "System.Object") returnfalse; return IsBasedOn(TestType.BaseType, BaseType);} #endregion #region creation de types///<summary> /// Créé une instance de l'élément demandé, s'il n'existe pas, créé une instance de l'élément par défaut. ///</summary> ///<param name="Id">Identifiant de l'élément à créer</param> ///<param name="parameters">Paramètres du constructeur</param> ///<returns>Objet de la classe de base</returns> public BaseClass Create(string Id, paramsobject[] parameters) { object Obj; try {Obj = creatable[Id].InvokeMember( null, BindingFlags.CreateInstance | BindingFlags.Public | BindingFlags.FlattenHierarchy | BindingFlags.Instance, null, null, parameters);} catch {Obj = creatable[defaultElement].InvokeMember( null, BindingFlags.CreateInstance | BindingFlags.Public | BindingFlags.FlattenHierarchy | BindingFlags.Instance, null, null, parameters);}
return (BaseClass)Obj; // <---- l'erreur a lieu ici, le cast est refusé alors que le type dérive bien} #endregion } Console.Out.WriteLine("Warny") Il y a 10 types de personnes Ceux qui comptent en binaire... et les autres
|
|
dimanche 18 février 2007 à 22:59:40 |
Re : Creation dynamique d'objet, InvalidCastException

coq
|
Salut, Tu devrais vérifier tes retours avant de les utiliser. Après à voir mais je ne suis pas sur que FlattenHierarchy aie sa place ici. Sinon jette un oeil à Activator.CreateInstance, ça devrait t'intéresser. /* coq MVP Visual C# CoqBlog*/
|
|
lundi 19 février 2007 à 08:10:59 |
Re : Creation dynamique d'objet, InvalidCastException

Warny
|
L'Activator.CreateInstance simplifie nettement la lecture du code mais n'arrange pas mon problème. Comment vérifier mon retour ? J'ai essayé de rajouter un As BaseClass, mais le compilateur le refuse.
J'ai fait un test où toutes mes entrées sont valides (toutes les classes lues dérivent de BaseClass). Même quand j'essaye d'instancier baseClass, j'ai la même erreur (voici la copie du message, c'est un peu frustrant)
L'exception System.InvalidCastException n'a pas été gérée Message="Impossible d'effectuer un cast d'un objet de type 'BaseBibliotheque.Parent' en type 'BaseBibliotheque.Parent'." Source="TestDynamique" StackTrace: à AutoCreation.Loader`1.Create(String Id, Object[] parameters) dans c:\projets\TestDynamique\TestDynamique\Loader.cs:ligne 163 à AutoCreation.Program.Main(String[] args) dans c:\projets\TestDynamique\TestDynamique\Program.cs:ligne 13 à System.AppDomain.nExecuteAssembly(Assembly assembly, String[] args) à System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args) à Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() à System.Threading.ThreadHelper.ThreadStart_Context(Object state) à System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) à System.Threading.ThreadHelper.ThreadStart()
Console.Out.WriteLine("Warny") Il y a 10 types de personnes Ceux qui comptent en binaire... et les autres
|
|
lundi 19 février 2007 à 17:30:51 |
Re : Creation dynamique d'objet, InvalidCastException

Warny
|
Réponse acceptée !
J'ai trouvé. Le problème vient d'un chargement partiel d'assembly voilà la solution :
A la place de Assembly assembly = Assembly.LoadFrom(Path);
Il faut mettre Assembly assembly = Assembly.Load(AssemblyName.GetAssemblyName(Path)); ;
Qui permet au framework de faire la correspondance dans le cache d'assembly entre celle qu'on charge et celles déjà chargées.
Console.Out.WriteLine("Warny") Il y a 10 types de personnes Ceux qui comptent en binaire... et les autres
|
|
mercredi 20 mai 2009 à 21:57:45 |
Re : Creation dynamique d'objet, InvalidCastException

EmacLi
|
Un grand merci Warny ! :)
|
|
Cette discussion est classée dans : type, classe, assembly, bindingflags, creatable
Répondre à ce message
Sujets en rapport avec ce message
Problème de type avec une assembly [ par dinytro ]
Bonjour, je souhaiterais récupérer le type d'une assembly que je charge avec la methode SampleAssembly = Assembly.LoadFrom(@pathAssembly); Ensuite je
Assembly.GetInterfaces() [ par jusob ]
Bonjour, J'ai un programme qui doit charger des DLLs. Ces DLLs implémentent l'interface PluginInterface. Programme principal: foreach (Type typ
Chargement dynamique de type [ par thiosyiasar ]
Bonjour a tous, Je voudrais faire un chargement dynamique d'assembly à partir d'un nom complet de type Par exemple, j'ai la valeur suivante "Syste
Dll, arguments & classe utilisateur [ par MyXiLo ]
Bonjour,Je voudrais passer un argument dérivant d'une classe utilisateur à une méthode d'une dll.J'ai un programme qui contient une classe MaClass et
DTD Classe??? [ par Globinours ]
J'aimerais générer une DTD à partir d'un TreeView mais là n'est pas le problème! En fait j'aimerais savoir si il existe une classe permettant d' écrir
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"))
Initialisations "Array-like", IEnumerable, Add() et lecture seule [ par Minotthor ]
Bonjour à tous, Soient Assembly et Sign, deux classes "maison" ... Je crée une classe Assembly qui contiendra en privé une List et j'aimerais pouvoi
Conversion d'un type d'une classe en la classe abstraite dont il herite [ par milo2009 ]
Bonjour, j'ai une methode qui retourne une classe abstraite. Dans la methode, j'instancie une classe qui herite de la classe abstraite attendu comme
réutilisation de classes dans C# [ par happyleptic ]
Bonjour,Je suis un habitué du C++, je m'essaye à C# en .Net.J'arrive à faire des trucs de base, je ne trouve pas ça plus pratique que du C++/win32, ma
Return et/ou structuration de classe [ par titi66 ]
BonjourJ'ai crée un classe Usines et 3 classes en dérivant. Voici le constructeur :public Usines(string</F
Livres en rapport
|
Derniers Blogs
[TECHDAYS 2012] SESSION WEBMATRIX 2 : LE COUTEAU SUISSE GRATUIT POUR VOS DéVELOPPEMENTS WEB - SLIDES[TECHDAYS 2012] SESSION WEBMATRIX 2 : LE COUTEAU SUISSE GRATUIT POUR VOS DéVELOPPEMENTS WEB - SLIDES par gpommier
Suite à la session que j'ai présenté sur WebMatrix 2, vous pouvez trouver les slides ici, ainsi que les démos en packages nuget : démos1 et démos2 J'en profite pour remercier chaleureusement tous ceux qui sont venus très nombreux à cette sess...
Cliquez pour lire la suite de l'article par gpommier [SHAREPOINT] LES SESSIONS TECHDAYS 2012.[SHAREPOINT] LES SESSIONS TECHDAYS 2012. par Patrick Guimonet
Voici donc pour ceux qui n'ont pas pu venir, ou ceux qui n'ont pas pu toutes les suivre la liste des sessions SharePoint aux TechDays 2012, que je mettrais à jour dès que les liens des vidéo seront disponibles. Ou ici : http...
Cliquez pour lire la suite de l'article par Patrick Guimonet TECHDAYS PARIS 2012 : SESSION PLEINIèRE JOUR 3TECHDAYS PARIS 2012 : SESSION PLEINIèRE JOUR 3 par ROMELARD Fabrice
Speaker: Bernard Ourghanlian Cette session est comme chaque jour transmise en live par BrainSonic, et j'ai donc suivi cette troisième pleinière par ce moyen sur mon iPad . Elle est dédiée comme chaque année à la mise en perspective de l'é...
Cliquez pour lire la suite de l'article par ROMELARD Fabrice MISHRA READER : UN LECTEUR RSS TRèS ZUNE STYLE EN OPEN SOURCE !MISHRA READER : UN LECTEUR RSS TRèS ZUNE STYLE EN OPEN SOURCE ! par Vko
Hier durant une session dédiée aux Techdays 2012, j'ai eu le plaisir d'annoncer la sortie de la Béta 2 de Mishra Reader. C'est quoi ? Pour les utilisateurs, c'est une vraie expérience de lecture de flux RSS sur Windows. Rien à voir avec les produit...
Cliquez pour lire la suite de l'article par Vko [FRAMEWORK 4] LES TASKS ET LE THREAD UI[FRAMEWORK 4] LES TASKS ET LE THREAD UI par fathi
Je viens de passer quelques temps au TechDay's et j'ai pu voir pas mal de session intéressante. Par contre une chose m'a un peu étonné lors de certaines de ces sessions qui abordaient les améliorations du framework .NET (donc le 4.5) : en gros, bea...
Cliquez pour lire la suite de l'article par fathi
Logiciels
Academy System (17.2.1.0)ACADEMY SYSTEM (17.2.1.0)Logiciel de gestion des établissements.
- élèves/étudiants (inscription, dossier, absence...)
-... Cliquez pour télécharger Academy System Easy-Planning (1.0.0.1)EASY-PLANNING (1.0.0.1)Basé sur les mêmes principes que MyPlanning, Easy-Planning permet de créer des plannings sous la ... Cliquez pour télécharger Easy-Planning COLLECTOR PLUS (3.00B)COLLECTOR PLUS (3.00B)COLLECTOR PLUS version 3.00B est un logiciel utilisant une base de données alimentée par :
- L... Cliquez pour télécharger COLLECTOR PLUS PONAMEDIA PREMIUM - HELLLOOO FLASH DEMO (V7.4)PONAMEDIA PREMIUM - HELLLOOO FLASH DEMO (V7.4)PONAMEDIA TV DEVIENS HELLLOOO FLASH
LA TV SUR VOTRE ORDINATEUR.
Toute une plateforme Multi... Cliquez pour télécharger PONAMEDIA PREMIUM - HELLLOOO FLASH DEMO LettresFaciles 2011 (8.0.0.1)LETTRESFACILES 2011 (8.0.0.1)LettresFaciles est un logiciel facilitant la création et la rédaction de lettres types.
Son inte... Cliquez pour télécharger LettresFaciles 2011
|