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 :

[C#][Entity] Problème de génération de code pour les MetaData via un fichier MetaData.tt


Sujet :

C#

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    92
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2006
    Messages : 92
    Points : 83
    Points
    83
    Par défaut [C#][Entity] Problème de génération de code pour les MetaData via un fichier MetaData.tt
    Bonjour

    Je me suis mis à .NET 4, il y a peu de temps... j'ai découvert Entity et aussi une extension Visual Studio pour générer des objets POCO (ici). J'ai du même coup découvert les fichiers d'extension .tt qui génère ces fichiers POCO. J'ai même trouvé une page qui explique comment personnaliser ces fameux fichiers .tt pour ajouter l'attribut MetadataType aux classes POCO (ici). Il explique même qu'en copiant le fichier .tt et en faisant 2, 3 modifs, on peut générer automatiquement les fichiers MetaData associés.

    Du coup, j'me suis dit :
    - c'est génial !
    - je vais créer un fichier ressources .resx avec les libellés de chaque champs POCO.
    - je vais modifier le fichier .tt qui génère mes fichiers MetaData pour ajouter à chaque champs l'attribut DisplayName avec la valeur de la ressource.

    Le but étant de :
    - centraliser tous mes libellés à un seul endroit
    - effectuer une correction de libellés qui soit directement répercutée sur l'ensemble des fichiers MetaData qui utilisent ce libellé.
    - exactement comme lorsqu'on modifie le fichier .edmx qui se répercute directement sur les fichiers POCO.

    Mon problème :
    - Dans le fichier .tt, le code ne connait pas la ressource que j'ai créé à la racine de mon projet.

    Debug :
    - Lorsque j'affiche le variable Environment.CurrentDirectory dans un fichier aspx de mon projet, j'obtiens :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    D:\dossier1\dossier2\Projects\MonProjet\bin\Debug
    - Lorsque j'affiche la variable Environment.CurrentDirectory dans les fichiers générés via le fichier .tt, j'obtiens :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    D:\Visual Studio 2010\Common7\IDE
    Il est donc normal que l'environnement d'exécution des fichiers .tt ne connaissent pas mon fichier ressources.
    Du coup, j'me suis dit :
    - no problem ! puisque le fichier .tt initial arrive à récupérer le fichier .edmx de mon projet pour générer les fichiers POCO why not me ?
    - j'ai juste à récupérer le fichier ressource de mon projet, le charger via la classe ResXResourceReader et atteindre mon but.

    Et là c'est le drame :
    1/ je n'arrive même pas à récupérer le dossier de mon projet où se trouve mon fichier .resx
    2/ en me disant que je trouverais une solution pour le 1/ plus tard, j'ai mis le chemin en dure
    3/ j'ai tenté de charger le fichier .resx mais l'environnement d'exécution du fichier .tt ne connait pas System.Windows.Forms.ResXResourceReader...
    4/ je ne sais pas comment ajouter une référence à System.Windows.Forms.dll dans D:\Visual Studio 2010\Common7\IDE

    Quelqu'un a-t-il déjà rencontré ce problème et trouvé une solution ?

    Bonne journée,

    Gat-

  2. #2
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    92
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2006
    Messages : 92
    Points : 83
    Points
    83
    Par défaut
    Je viens d'avancer un peu sur ma problèmatique grâce à cette page (ici).
    En utilisant la directive assembly et import, je peux utiliser la classe ResXResourceReader.
    Pour cela, il faut ajouter en haut du fichier .tt le code suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    <#@ assembly name="System.Windows.Forms" #>
    <#@ import namespace="System.Resource" #>
    Maintenant il me faut récupérer le chemin vers mon fichier .resx
    Si quelqu'un a une idée, une petite piste, je suis preneur !

    Ensuite, je viens de penser à une Nième problèmatique :
    - Comment dans le fichier .tt détecter que le fichier .resx a été ou non modifié pour regénérer les classes MetaData ? (Comme lorsqu'on modifie un fichier .edmx et que les modifs sont répercutées sur les classes POCO)

  3. #3
    Membre émérite
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Avril 2006
    Messages
    1 627
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Avril 2006
    Messages : 1 627
    Points : 2 331
    Points
    2 331
    Par défaut
    Je viens d'avoir le même souci, je te donne ma solution :

    1. définition de l'en-tête du tt de telle sorte :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <#@ template debug="true" hostspecific="true" language="C#" #>
    ce qui importe ici est hostspecific="true", pour la suite

    Ensuite, récupérer le chemin courant de ton .tt :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    String path = this.Host.ResolvePath("");
    Si hostspecific="false", exception levée lors des appels sur this.Host

    A partir de là, path donne le chemin de ton répertoire contenant ton tt, il te suffit d'appliquer un path relatif pour cibler ton répertoire de ressources le cas échéant

  4. #4
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    92
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2006
    Messages : 92
    Points : 83
    Points
    83
    Par défaut
    OMG !!! Merci énormément Arnaud !
    Tu as résolu en 2 ligne mon problème pour récupérer le path du fichier ressource.

    J'étais parti sur une solution délirante que j'ai trouvé via notre ami google :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    EnvDTE.DTE dte = (EnvDTE.DTE)((IServiceProvider)this.Host)
                        .GetService(typeof(EnvDTE.DTE));
    A partir de là, j'ai récupéré les projets de la solution, les items des projets...
    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
    string resxFileName = "MyResource.resx";
    string resxFilePath = "";
    bool found = false;
    IEnumerator enumProject = dte.Solution.Projects.GetEnumerator();
     
    while (!found && enumProject.MoveNext()) {
        Project p = (Project)enumProject.Current;
        IEnumerator enumItem = p.ProjectItems.GetEnumerator();
     
        while (found! && enumItem.MoveNext()) {
            ProjectItem item = (ProjectItem)enumItem.Current;
     
            if (item.Name.EndWith("\\" + resxFile)) {
                found = true;
                resxFilePath = item.Name;
            }
        }
    }
    Dommage que les fichiers .tt ne soient pas pris en compte dans VS (coloration syntaxique & autocompletion).

    Du coup, saurais-tu comment faire pour surveiller le fichier ressource afin qu'une modification dessus, déclenche la génération des fichiers MetaData à partir de ce fichier .tt ??? (exactement comme pour une modifs d'un fichier .edmx)

  5. #5
    Membre émérite
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Avril 2006
    Messages
    1 627
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Avril 2006
    Messages : 1 627
    Points : 2 331
    Points
    2 331
    Par défaut
    Pour la coloratin synthaxique et complétion, il y a des plugins : http://visualstudiogallery.msdn.micr...-3715e90c1a23/

    redémarre VS, et magie !!

    Pour déterminer le changement, heu, joker. Eventuellement automatiser la génération des T4 dans une instruction PreBuild ? J'essaierais de trouver des infos sinon

  6. #6
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    92
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2006
    Messages : 92
    Points : 83
    Points
    83
    Par défaut
    Génial cette extension !!! Merci beaucoup Arnaud ! C'est beaucoup plus simple maintenant. Pour la détection d'une modification du fichier ressources, je laisse tomber De toute façon, ce n'est qu'un bonus car je peux le lancer manuellement.

    Pour ce qui est du retraitement des fichiers templates .tt avant le build, j'ai trouvé un site qui fournit une solution (ici dans la partie Regenerating the code automatically), En gros, il faut :
    - Installer Visual Studio 2010 SDK (ici)
    - Installer Visual Studio 2010 Visualization & Modeling SDK (ici)
    - Ajouter à la fin du fichier .csproj le code suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    <Import Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\TextTemplating\v10.0\Microsoft.TextTemplating.targets" />
    <PropertyGroup>
       <TransformOnBuild>true</TransformOnBuild>
    </PropertyGroup>
    (Pour plus d'infos sur les propriétés disponibles, ouvrez directement le fichier Microsoft.TextTemplating.targets, tout y est décrit)

    - Ensuite dans les fichiers .tt, il faut modifier la directive include pour aller chercher le fichier EF.Utility.CS.ttinclude avec le chemin complet car sinon au moment du build, des erreurs surviennent car ce fichier sera introuvable :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Failed to resolve include text for file:C:\...\Sources\MyProject\MyProject.Data\EF.Utility.CS.ttinclude. Line=-1, Column=-1
    En effet, le fichier n'est pas trouvé car l'environnement d'exécution n'est plus "D:\Visual Studio 2010\Common7\IDE".
    D'ailleurs si quelqu'un connait le moyen de définir un chemin relatif vers le fichier .ttinclude genre "$(MSVisualStudioIDEPath)\EF.Utility.CS.ttinclude", je suis preneur

    Au sujet de mon post initial, je considère qu'il est résolu.
    Merci encore Arnaud !

  7. #7
    Membre émérite
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Avril 2006
    Messages
    1 627
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Avril 2006
    Messages : 1 627
    Points : 2 331
    Points
    2 331
    Par défaut
    Il me semble que Directory.GetCurrentDirectory() renvoie par défaut le path de vs2010 quand exécuté dans un .tt

  8. #8
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    92
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2006
    Messages : 92
    Points : 83
    Points
    83
    Par défaut
    Oui lorsque j'édite mon fichier .tt et que j'enregistre, le .tt est directement exécuté et le path par défaut est bien le dossier de VS2010. Par contre, lorsque je lance une génération, le path par défaut est celui de mon appli.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Problème de génération du code
    Par dush_ dans le forum BOUML
    Réponses: 6
    Dernier message: 31/05/2008, 19h14
  2. Réponses: 8
    Dernier message: 09/02/2008, 17h21
  3. [Hibernate Tools]Problème de génération de code !
    Par Kevin12 dans le forum Hibernate
    Réponses: 2
    Dernier message: 05/02/2008, 12h28
  4. [XSLT] Problème de génération de code javascript (inclure) via XSLT
    Par fragmonster dans le forum XSL/XSLT/XPATH
    Réponses: 3
    Dernier message: 23/04/2007, 14h49
  5. [Lomboz] Génération de code pour EJB
    Par paikan dans le forum Eclipse Java
    Réponses: 2
    Dernier message: 09/07/2003, 14h28

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