IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C# Discussion :

recomposition d'un objet à partir d'une carte


Sujet :

C#

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Développeur Web
    Inscrit en
    Décembre 2004
    Messages
    97
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Décembre 2004
    Messages : 97
    Par défaut recomposition d'un objet à partir d'une carte
    Bonjour,

    je vais essayé d'exposer mon problème le plus clairement possible...

    J'ai une classe User, une classe DataObject et dans une base de données une table Users.
    - La classe User étend la classe DataObject.
    - La classe DataObject possède, entre autre, une propriété fieldsmap.
    - Les propriétés de ma classe User correspondent aux champs de ma table Users.
    - Dans ma classe User, j'initialise la propriété fieldsmap ; qui est en fait un tableau associatif qui représente une carte de la table Users
    - Ma classe DataObject possède plusieurs méthodes dont une méthode findAll(...) qui me renvoie un tableau d'objets.

    Ce que je cherche à faire :
    Je souhaiterais que lorsque j'appelle la méthode findAll(...) ma classe DataObject renvoie un tableau d'objet de type User qu'elle aurait recomposé grâce à la carte fieldsMap.
    En gros, j'essaie de faire en sorte que la classe DataObject soit capable de construire un objet par rapport à la carte fieldsMap
    Tout est clair dans ma tête, je câle niveau syntaxe et technique.

    On parvient à le faire en php, ça doit certainement être possible mais comment ...

    Ce qui est décrit ci-dessus inteviendra dans un projet asp.net

    merci,

    Excellente soirée,

    Philippe

    PS : ...Petite précision, je fais essentiellement du php et de l'asp classique , je débute en .net

  2. #2
    Rédacteur

    Avatar de Jérôme Lambert
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Novembre 2003
    Messages
    4 451
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2003
    Messages : 4 451
    Par défaut
    J'aime bien ce genre de question

    Pour y arriver, il faudra :
    • Une bonne dose de Réflexion (System.Reflection);
    • Un soupçon de notion d'héritage;
    • Et une pincée de logique;
    Donc, je reprend tes explications avec un petit exemple :

    Une table table_User dans la base de données :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Champs 
    field_id int
    field_nom varchar(50)
    Une classe DataObject :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    public abstract class DataObject
    {
    private string m_tablename = string.Empty;
     
    public DataObject(string tb_name)
    { this.m_tablename = tb_name; }
     
    public abstract Dictionnary<string, string> fieldsmap();
    }
    Une classe User qui hérite de la classe DataObject et qui va donc implémenter la méthode fieldsmap :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    public class User : DataObject
    {
    private int m_Id = 0;
    private string m_Nom = string.Empty;
     
    public User(string tb_name) : base(tb_name)
    { }
     
    public override Dictionnary<string, string> fieldsmap()
    {
    // La clé est le nom du champ
    // La valeur est le nom de la propriété correspondante dans l'objet courant
    Dictionnary<string, string> objFieldsMap = new Dictionary<string, string>();
     
    objFieldsMap.Add("field_id", "Id");
    objFieldsMap.Add("field_nom", "Nom");
     
    return objFieldsMap;
    }
     
    public int Id
    {
    get{ return m_Id; }
    set{ m_Id = value; }
    }
     
    public string Nom
    {
    get{ return m_Nom; }
    set{ m_Nom = value; }
    }
    }
    Maintenant, il reste à écrire cette fameuse méthode FindAll qui va récupérer la liste des tuples dans table_User et qui vont être transformés en objets User. Où va-t-on écrire ce code ? Dans DataObject évidemment pour en faire une méthode "générique". Je suppose que tu exécute ta requête avec un DataReader, je ne vais donc détailler ici que le code parcourant chaque row renvoyée par le DataReader :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    public List<User> FindAll()
    {
    Dictionary<string, string> objFieldsMap = this.fieldsMap();
     
    // Création de la query, tu peux te servir du dictionnaire renvoyé par fieldsmap pour construitre la méthode select de manière dynamique
     
    // Ta requête est exécutée et on se retrouve avec objDataReader prêt à être parcouru :
     
    // Cet objet list va contenir tous les objets User
    List<User> objUsers = new List<User>;
    while(objDataReader.Read())
    {
    // On va tout d'abord créer une instance de l'objet courant, dans notre cas, ce sera User
    DataObject objObjectToFill = Activator.CreateInstance(this.GetType()) as DataObject;
     
    // On est sur la ligne courante, on va donc récupérer chaque valeur grâce à objFieldsMap
    foreach(string fieldname in objFieldsMap.Values)
    {
    object value = objDataReader[fieldname];
     
    // Maintenant, on va remplir la bonne propriété de l'objet objObjectToFill grâce à la réflexion
    System.Reflection.PropertyInfo objPropertyInfo = this.GetType().GetProperty(objFieldsMap[fieldName]);
    objPropertyInfo.SetValue(objObjectToFill, value, null);
    }
     
    // Une fois que l'objet est rempli, il reste plus qu'à l'ajouter à la liste
    objUsers.Add(objObjectToFill);
    }
     
    // Quand on a parcouru toutes les rows (on oublie pas de fermer l'objet command :p)
    // Et on renvoie l'objet list
    return objUsers;
    }
    Voilà, je ne peux pas te garantir que ça va fonctionner comme ça car j'ai écrit ça sans le tester mais tu as le principe.

    Si tu as quelques soucis de compréhension avec certains points, n'hésite pas, je me doute que ça ne doit pas être facile de passer de php/asp à asp.net.

  3. #3
    Membre confirmé
    Profil pro
    Développeur Web
    Inscrit en
    Décembre 2004
    Messages
    97
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Décembre 2004
    Messages : 97
    Par défaut
    Bonjour,

    Déjà ! un grand merci, Cardi, pour ces infos et exemples ! Ca éclaircit déjà beaucoup mes pensées !

    La réflexion : je suis justement tombé hier soir sur ce post [VS2005][C#] Création et recherche dynamique d'objet

    Il y a encore un point qui m'inquiète :

    Le but de ma classe DataObject, c'est que plusieurs type d'objet pourront l'étendre (une classe User, une classe Company, une classe News, ...), si je prends par exemple la fonction List<User> FindAll()
    Comment lui spécifier le type d'objet (User ? Company ? News ?) qu'elle va devoir me rendre ? Je suppose que c'est ici que va intervenir, entre autre, la réflexion ?

    Bon appétit,

    Phil-

  4. #4
    Rédacteur

    Avatar de Jérôme Lambert
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Novembre 2003
    Messages
    4 451
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2003
    Messages : 4 451
    Par défaut
    Citation Envoyé par Philoulheinz Voir le message
    Le but de ma classe DataObject, c'est que plusieurs type d'objet pourront l'étendre (une classe User, une classe Company, une classe News, ...), si je prends par exemple la fonction List<User> FindAll()
    Comment lui spécifier le type d'objet (User ? Company ? News ?) qu'elle va devoir me rendre ? Je suppose que c'est ici que va intervenir, entre autre, la réflexion ?

    Oui tout à fait, grâce à la réflexion, on va pouvoir créer tout simplement une instance du type courant.

    Tout d'abord, il faut savoir qu'avec la réflexion, on joue beaucoup avec la classe Type qui est le "coeur" de la réflexion dans le sens que c'est grâce à cette classe abstraite qu'on va pouvoir accéder aux métadonnées d'une classe donnée.

    Pour ce faire, tout les types du framework ainsi que ceux que tu vas créer à l'avenir proposent la méthode GetType() pour récupérer une instance Type de l'objet en question.


    En écrivant ceci à l'intérieur de la classe, tu vas pouvoir récupérer l'objet Type correspondant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Type monType = this.GetType();
    Si tu as écrit ceci dans :
    • La classe User, tu auras les informations de la classe User;
    • La classe Company, tu auras les informations de la classe Company;
    • La classe DataObject, tu auras les informations de la classe qui hérite de DataObject (vive l'héritage);
    Voila, tu as ton instance de Type qui te donne les informations de la classe courante mais c'est tout. Toi il te faut une instance de User, Company, ... C'est ici qu'intervient la classe Activator avec sa méthode statique CreateInstance qui permet d'instancier un objet à partir d'un Type.

    Si on continue le code ci dessous, on aura :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    object monObjet = System.Activaror.CreateInstance(monType);
    Comme tu peux le voir, on récupère un instance de type Object qui est la classe de base du framework Dotnet, tout objet dérive du type Object que tu le veuilles ou pas, tu n'as pas le choix

    Il ne te reste plus qu'à caster correctement l'objet précédemment instancié. Comme tu peux le voir dans le code que je t'ai proposé hier, j'ai casté l'objet en DataObject directement dans la classe du même nom. La raison est que ça te permet d'avoir un code générique que tu n'auras pas besoin de re-écrire dans ta classe Company, ni dans User, encore moins dans une autre classe.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    DataObject monDataObject = monObjet as DataObject;
    Cependant, si tu désires de spécialiser ton code dans la classe User par exemple, rien ne t'empêche de caster l'objet en User.

    Au passage, je viens de remarquer uen faute de ma part dans la méthode FindAll que je t'ai proposé ; Dedans, j'utilise des types User alors que le code doit être générique pour ne pas se soucier du type dont il a affaire, pour cela, j'aurais du écrire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    public List<DataObject> FindAll()
    {
     ...
     List<DataObject> objDataObjects = new List<DataObject>(); // Et non List<User> objUsers = new List<User>();
    }
    Voila, en espérant ne pas m'être trop étalé, n'hésite pas si il reste des points sombres (je ne sais pas du tout si tu as des bonnes notions de tout ce qui est héritage et compagnie).

  5. #5
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Par défaut
    Sinon tu peux utiliser LINQ to SQL... c'est moins générique, mais c'est tellement pratique de créer son mapping objet/relationnel en quelques clics...
    Par contre seul SQL Server est complètement supporté du moins jusqu'à ce que les éditeurs des autres SGBD nous sortent le provider ad hoc...

  6. #6
    Membre confirmé
    Profil pro
    Développeur Web
    Inscrit en
    Décembre 2004
    Messages
    97
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Décembre 2004
    Messages : 97
    Par défaut
    Un grand merci, Cardi, avec toutes ces belles paroles, j'ai quasi plus qu'à mettre en musique

    J'ai hâte de m'y mettre, ça va être chouette à implémenter tout ça.

    Merci, TomLev, pour ton information mais comme tu le précises avec "LINQ to SQL" seul SQLServer est supporté...pour l'instant

Discussions similaires

  1. nommer un objet à partir d'une variable String
    Par kobrapercussions dans le forum Langage
    Réponses: 12
    Dernier message: 13/03/2007, 13h19
  2. Réponses: 7
    Dernier message: 29/12/2006, 12h56
  3. Réponses: 21
    Dernier message: 22/06/2006, 21h11
  4. Réponses: 6
    Dernier message: 18/01/2006, 16h26
  5. Generer des objets aleatoirement sur une carte
    Par K20 dans le forum Langage
    Réponses: 13
    Dernier message: 24/12/2005, 16h19

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo