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
Accéder à une classe d’un autre assembly [ par Souliabdo ]
Bonjour, J’ai une e solution qui contient deux projets, mon problème est que je n’arrive pas à accéder, depuis le projet de démarrage, aux classes d
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
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
Récupérer la description d'une méthode "summary" [ par bmouget ]
Bonjour,Aprés chargement d'une Assembly, je voudrais récupérer la description d'une fonction, celle que l'on saisi dans /// .Voici mon code :
classe et assembly [ par chris81 ]
bonjour je viens de me mettre au c# et j'y comprend pas gd chose :)j'aimerais savoir comment on fait pour appeler une classe et comment on fait pour c
Livres en rapport
|
Derniers Blogs
TECHDAYS PARIS 2010 : SHAREPOINT 2010 POUR LES DéVELOPPEURSTECHDAYS PARIS 2010 : SHAREPOINT 2010 POUR LES DéVELOPPEURS par ROMELARD Fabrice
Animé par: Laurent Cotton Le développement dans SharePoint 2010 passe par plusieurs axes qui seront évoqués dans cette session, mais plus particulièrement les développements simples lié au besoin Business Business Connectivity Services Ce BCS es...
Cliquez pour lire la suite de l'article par ROMELARD Fabrice TECHDAYS PARIS 2010 : PLEINIèRE DERNIER JOURTECHDAYS PARIS 2010 : PLEINIèRE DERNIER JOUR par ROMELARD Fabrice
Cette session est la dernière pleinière de ces 3 jours de TechDays Paris 2010. Généralement, cette troisième journée est plus axée sur l'avenir vu par Microsoft. Après un retour sur l'avenir vu par la Science Fiction ou par ...
Cliquez pour lire la suite de l'article par ROMELARD Fabrice UNE JOLIE-HORLOGE ET PAS QU'UN PEU !UNE JOLIE-HORLOGE ET PAS QU'UN PEU ! par neodante
Pour les possesseurs d'iPhone, ça y est Bijin Tokei - qui se traduit littéralement en Français par " Jolie Horloge " - est arrivé et GRATUITEMENT s'il vous plaît ! Après la version Tokyo, Hokkaido, night club, racing, Gal, "pour les mademoiselles'", . voi...
Cliquez pour lire la suite de l'article par neodante TECHDAYS PARIS 2010 : CONNECTEZ VOS DONNéES à SHAREPOINT 2010 AVEC LES BUSINESS CONNECTIVITY SERVICESTECHDAYS PARIS 2010 : CONNECTEZ VOS DONNéES à SHAREPOINT 2010 AVEC LES BUSINESS CONNECTIVITY SERVICES par ROMELARD Fabrice
Animé par: Gaetan Bouveret et Julien Chomarat Business Connectivity Services (BCS) est dans SharePoint 2010 la version 2 de Business Data Catalog (BDC dans SharePoint 2007). Il s'agit de la solution permettant de visualiser des données provenan...
Cliquez pour lire la suite de l'article par ROMELARD Fabrice [DIVERS] SUIVRE VOS SéRIES PRéFéRéS SUR LA TOILE[DIVERS] SUIVRE VOS SéRIES PRéFéRéS SUR LA TOILE par orion
Comme de nombreux geek, je suis un grand amateur de série TV et je rate régulièrement des épisodes de mes séries préférés. Une solution s'offre à vous avec ce merveilleux site : Tv Gorge - www.tvgorge.com Moteur de recherche à l'appui, vous pouvez ...
Cliquez pour lire la suite de l'article par orion
Logiciels
DB-MAIN (9.1.0)DB-MAIN (9.1.0)DB-MAIN is a data-modeling and data-architecture tool. It is designed to help developers and anal... Cliquez pour télécharger DB-MAIN Xilisoft DPG Convertisseur (5.1.37.0120)XILISOFT DPG CONVERTISSEUR (5.1.37.0120)Xilisoft DPG Convertisseur offre aux fans de Nintendo DS une bonne solution leur permettant de dé... Cliquez pour télécharger Xilisoft DPG Convertisseur GraphicsGale (2.01.01)GRAPHICSGALE (2.01.01)GraphicsGale est un logiciel de PixelArt avec de nombreuse fonctionnalités permettant de réalisé ... Cliquez pour télécharger GraphicsGale Architecte 3D (Platinum 2010)ARCHITECTE 3D (PLATINUM 2010)Architecte 3D Platinium vous permet de concevoir facilement les plans votre future maison, de l'é... Cliquez pour télécharger Architecte 3D TeamViewer 5 (TeamViewer 5)TEAMVIEWER 5 (TEAMVIEWER 5)Dépanner un ami,expliquer une manipulation devient un jeu d'enfant.
Prise en main d'un autre ord... Cliquez pour télécharger TeamViewer 5
|