<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-3773144983876508185</id><updated>2011-10-20T21:28:44.458+02:00</updated><category term='Evenements'/><category term='C#'/><category term='Visual Studio'/><category term='ASP.Net'/><category term='divers'/><category term='Developpez.com'/><category term='Workflow Foundation'/><category term='Entity Framework'/><category term='Sharepoint'/><title type='text'>Paul Musso &amp; le .Net</title><subtitle type='html'>Blog sur les dernières technologies .Net : Extensibilité Visual Studio, Workflows, POA, Sharepoint</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://populnet.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3773144983876508185/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://populnet.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Popul</name><uri>http://www.blogger.com/profile/13339110117970769017</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://2.bp.blogspot.com/__831xq1hNEM/SXSGahZtTOI/AAAAAAAAAC0/YTZpJgy1wUI/S220/photo.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>28</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-3773144983876508185.post-7400364154147682393</id><published>2009-01-27T13:16:00.003+01:00</published><updated>2009-01-27T13:19:45.952+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><title type='text'>Astuce du jour : Copier un fichier avec la classe Stream</title><content type='html'>Voici une petite méthode qui permet de copier un fichier dans un nouveau à l'aide de la classe Stream :&lt;br /&gt;&lt;div class="csharpcode"&gt;&lt;br /&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; CopierFichier(&lt;span class="kwrd"&gt;string&lt;/span&gt; pNomFichier1, &lt;span class="kwrd"&gt;string&lt;/span&gt; pNomFichier2)&lt;/pre&gt;&lt;pre&gt;{&lt;/pre&gt;&lt;pre class="alt"&gt;    &lt;span class="rem"&gt;// Initialisation des flux&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre&gt;    Stream streamFichier1 = &lt;span class="kwrd"&gt;new&lt;/span&gt; StreamReader(pNomFichier1).BaseStream ;&lt;/pre&gt;&lt;pre class="alt"&gt;    Stream streamFichier2 = &lt;span class="kwrd"&gt;new&lt;/span&gt; FileStream(pNomFichier2, FileMode.Create, FileAccess.Write);&lt;/pre&gt;&lt;br /&gt;&lt;pre class="alt"&gt;    &lt;span class="rem"&gt;// Initialisation du buffer à 32 Ko&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre&gt;    &lt;span class="kwrd"&gt;int&lt;/span&gt; taille = 1024 * 32;&lt;/pre&gt;&lt;pre class="alt"&gt;    Byte[] buffer = &lt;span class="kwrd"&gt;new&lt;/span&gt; Byte[taille];&lt;/pre&gt;&lt;pre&gt;    &lt;span class="kwrd"&gt;int&lt;/span&gt; bytesRead = 0;&lt;/pre&gt;&lt;br /&gt;&lt;pre&gt;    &lt;span class="rem"&gt;// Copie du flux 1 vers le flux 2&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;do&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre&gt;    {&lt;/pre&gt;&lt;pre class="alt"&gt;        bytesRead = streamFichier1.Read(buffer, 0, taille);&lt;/pre&gt;&lt;pre&gt;        streamFichier2.Write(buffer, 0, bytesRead);&lt;/pre&gt;&lt;pre class="alt"&gt;    }&lt;/pre&gt;&lt;br /&gt;&lt;pre&gt;    &lt;span class="kwrd"&gt;while&lt;/span&gt; (bytesRead &amp;gt; 0);&lt;/pre&gt;&lt;pre&gt; &lt;/pre&gt;&lt;pre&gt;    &lt;span class="rem"&gt;// Fermeture des flux&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;    streamFichier1.Close();&lt;/pre&gt;&lt;pre&gt;    streamFichier2.Close();&lt;/pre&gt;&lt;pre class="alt"&gt;} &lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;L'argument pNomFichier1 correspond au nom du fichier à copier et le 2ème correspond au nom du fichier créé par la fonction.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3773144983876508185-7400364154147682393?l=populnet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://populnet.blogspot.com/feeds/7400364154147682393/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3773144983876508185&amp;postID=7400364154147682393' title='2 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3773144983876508185/posts/default/7400364154147682393'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3773144983876508185/posts/default/7400364154147682393'/><link rel='alternate' type='text/html' href='http://populnet.blogspot.com/2009/01/astuce-du-jour-copier-un-fichier-avec.html' title='Astuce du jour : Copier un fichier avec la classe Stream'/><author><name>Popul</name><uri>http://www.blogger.com/profile/13339110117970769017</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://2.bp.blogspot.com/__831xq1hNEM/SXSGahZtTOI/AAAAAAAAAC0/YTZpJgy1wUI/S220/photo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3773144983876508185.post-1973361049942996327</id><published>2009-01-26T16:51:00.005+01:00</published><updated>2009-01-26T17:07:19.623+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Entity Framework'/><title type='text'>Entity Framework et les types complexes</title><content type='html'>Les types complexes font parti des fonctionnalités manquantes de l'éditeur de modèle EDM fourni avec Visual Studio 2008. Pour pouvoir en bénéficier, il est nécessaire de modifier les fichiers CSDL (schéma conceptuel) et MSL (schéma de liaison) ainsi que de modifier les classes d'entité.&lt;br /&gt;&lt;br /&gt;Tout d'abord à quoi sert un type complexe ? Dans une entité, il peut être utile de séparer dans un nouveau type plusieurs variables cohérentes entre elles. Par exemple, la classe Client est composée des variables suivantes :&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Id&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Nom&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Prenom&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Telephone&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Pays&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Rue&lt;/li&gt;&lt;br /&gt;&lt;li&gt;CodePostal&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Ville&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Les 4 dernières variables sont en relation avec l'adresse du client. Il serait donc logique de les déplacer dans une classe appelée Adresse, d'où l'utilité du type complexe.&lt;br /&gt;&lt;br /&gt;Dans Entity Framework, un type complexe ne contient aucun identifiant et il est forcément relié à une entité mère, Client pour notre exemple. Comme avec l'héritage "1 table -&gt; plusieurs entités", c'est une autre manière de définir plusieurs entités pour une seule table.&lt;br /&gt;&lt;br /&gt;Si vous souhaitez mettre en place un type complexe, vous serez obligé d'utiliser directement les fichiers CSDL, MSL et SSDL. L'éditeur de modèle EDM cache ses 3 fichiers dans l'assemblage du projet en tant que ressources embarquées. Pour les extraire, j'ai utilisé &lt;a href="http://www.red-gate.com/products/reflector/"&gt;Reflector &lt;/a&gt;et l'addin &lt;a href="http://www.denisbauer.com/NETTools/FileDisassembler.aspx"&gt;FileDisassembler &lt;/a&gt;permettant d'extraire tous les fichiers composant un assemblage.&lt;br /&gt;&lt;br /&gt;Une autre solution est de passer par l'utilitaire "EdmGen.exe" qui permet de générer les fichiers CSDL, MSL, SSDL. Cependant, vous perdez tout le bénéfice de définir graphiquement votre modèle via l'éditeur d'EDM (une erreur de frappe est vite arrivé dans un fichier XML …).&lt;br /&gt;&lt;br /&gt;Pour l'exemple, je pars de la base de données utilisée dans mon &lt;a href="http://pmusso.developpez.com/tutoriels/dotnet/entity-framework/introduction/"&gt;article&lt;/a&gt; publié sur developpez.com. Vous trouverez les scripts SQL Serveur 2005 de la base dans l'archive, à la fin de ce billet.&lt;br /&gt;&lt;br /&gt;En 1er lieu, voici le schéma logique (SSDL) :&lt;br /&gt;&lt;div class="csharpcode"&gt;&lt;br /&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Schema&lt;/span&gt; &lt;span class="attr"&gt;Namespace&lt;/span&gt;&lt;span class="kwrd"&gt;="helloentityfxModel.Store"&lt;/span&gt; &lt;span class="attr"&gt;Alias&lt;/span&gt;&lt;span class="kwrd"&gt;="Self"&lt;/span&gt; &lt;span class="attr"&gt;Provider&lt;/span&gt;&lt;span class="kwrd"&gt;="System.Data.SqlClient"&lt;/span&gt; &lt;span class="attr"&gt;ProviderManifestToken&lt;/span&gt;&lt;span class="kwrd"&gt;="2005"&lt;/span&gt; &lt;span class="attr"&gt;xmlns:store&lt;/span&gt;&lt;span class="kwrd"&gt;="http://schemas.microsoft.com/ado/2007/12/edm/EntityStoreSchemaGenerator"&lt;/span&gt; &lt;span class="attr"&gt;xmlns&lt;/span&gt;&lt;span class="kwrd"&gt;="http://schemas.microsoft.com/ado/2006/04/edm/ssdl"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;  &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;EntityContainer&lt;/span&gt; &lt;span class="attr"&gt;Name&lt;/span&gt;&lt;span class="kwrd"&gt;="CustomModelStoreContainer"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;EntitySet&lt;/span&gt; &lt;span class="attr"&gt;Name&lt;/span&gt;&lt;span class="kwrd"&gt;="Client"&lt;/span&gt; &lt;span class="attr"&gt;EntityType&lt;/span&gt;&lt;span class="kwrd"&gt;="helloentityfxModel.Store.Client"&lt;/span&gt; &lt;span class="attr"&gt;store:Type&lt;/span&gt;&lt;span class="kwrd"&gt;="Tables"&lt;/span&gt; &lt;span class="attr"&gt;Schema&lt;/span&gt;&lt;span class="kwrd"&gt;="dbo"&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;  &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;EntityContainer&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;  &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;EntityType&lt;/span&gt; &lt;span class="attr"&gt;Name&lt;/span&gt;&lt;span class="kwrd"&gt;="Client"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Key&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;      &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;PropertyRef&lt;/span&gt; &lt;span class="attr"&gt;Name&lt;/span&gt;&lt;span class="kwrd"&gt;="Id"&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Key&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Property&lt;/span&gt; &lt;span class="attr"&gt;Name&lt;/span&gt;&lt;span class="kwrd"&gt;="Id"&lt;/span&gt; &lt;span class="attr"&gt;Type&lt;/span&gt;&lt;span class="kwrd"&gt;="int"&lt;/span&gt; &lt;span class="attr"&gt;Nullable&lt;/span&gt;&lt;span class="kwrd"&gt;="false"&lt;/span&gt; &lt;span class="attr"&gt;StoreGeneratedPattern&lt;/span&gt;&lt;span class="kwrd"&gt;="Identity"&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Property&lt;/span&gt; &lt;span class="attr"&gt;Name&lt;/span&gt;&lt;span class="kwrd"&gt;="Nom"&lt;/span&gt; &lt;span class="attr"&gt;Type&lt;/span&gt;&lt;span class="kwrd"&gt;="varchar"&lt;/span&gt; &lt;span class="attr"&gt;MaxLength&lt;/span&gt;&lt;span class="kwrd"&gt;="50"&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Property&lt;/span&gt; &lt;span class="attr"&gt;Name&lt;/span&gt;&lt;span class="kwrd"&gt;="Prenom"&lt;/span&gt; &lt;span class="attr"&gt;Type&lt;/span&gt;&lt;span class="kwrd"&gt;="varchar"&lt;/span&gt; &lt;span class="attr"&gt;MaxLength&lt;/span&gt;&lt;span class="kwrd"&gt;="50"&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;amp;gt&lt;span style="font-family:Georgia,serif;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Property&lt;/span&gt; &lt;span class="attr"&gt;Name&lt;/span&gt;&lt;span class="kwrd"&gt;="Pays"&lt;/span&gt; &lt;span class="attr"&gt;Type&lt;/span&gt;&lt;span class="kwrd"&gt;="varchar"&lt;/span&gt; &lt;span class="attr"&gt;MaxLength&lt;/span&gt;&lt;span class="kwrd"&gt;="50"&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Property&lt;/span&gt; &lt;span class="attr"&gt;Name&lt;/span&gt;&lt;span class="kwrd"&gt;="Rue"&lt;/span&gt; &lt;span class="attr"&gt;Type&lt;/span&gt;&lt;span class="kwrd"&gt;="varchar"&lt;/span&gt; &lt;span class="attr"&gt;MaxLength&lt;/span&gt;&lt;span class="kwrd"&gt;="100"&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Property&lt;/span&gt; &lt;span class="attr"&gt;Name&lt;/span&gt;&lt;span class="kwrd"&gt;="CodePostal"&lt;/span&gt; &lt;span class="attr"&gt;Type&lt;/span&gt;&lt;span class="kwrd"&gt;="char"&lt;/span&gt; &lt;span class="attr"&gt;MaxLength&lt;/span&gt;&lt;span class="kwrd"&gt;="5"&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Property&lt;/span&gt; &lt;span class="attr"&gt;Name&lt;/span&gt;&lt;span class="kwrd"&gt;="Telephone"&lt;/span&gt; &lt;span class="attr"&gt;Type&lt;/span&gt;&lt;span class="kwrd"&gt;="char"&lt;/span&gt; &lt;span class="attr"&gt;MaxLength&lt;/span&gt;&lt;span class="kwrd"&gt;="10"&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Property&lt;/span&gt; &lt;span class="attr"&gt;Name&lt;/span&gt;&lt;span class="kwrd"&gt;="Ville"&lt;/span&gt; &lt;span class="attr"&gt;Type&lt;/span&gt;&lt;span class="kwrd"&gt;="varchar"&lt;/span&gt; &lt;span class="attr"&gt;MaxLength&lt;/span&gt;&lt;span class="kwrd"&gt;="50"&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;  &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;EntityType&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Schema&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;Pour ce fichier, rien de spécial à signaler si ce n'est la description de la table et des propriétés (colonnes) qui la composent. Aucune référence au type complexe n'apparait. Ceci est tout à fait normal puisque c'est le schéma logique faisant référence à la structure de la base de données.&lt;br /&gt;&lt;br /&gt;Passons maintenant au schéma conceptuel (CSDL) :&lt;br /&gt;&lt;div class="csharpcode"&gt;&lt;br /&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Schema&lt;/span&gt; &lt;span class="attr"&gt;Namespace&lt;/span&gt;&lt;span class="kwrd"&gt;="CustomModel"&lt;/span&gt; &lt;span class="attr"&gt;Alias&lt;/span&gt;&lt;span class="kwrd"&gt;="Self"&lt;/span&gt; &lt;span class="attr"&gt;xmlns&lt;/span&gt;&lt;span class="kwrd"&gt;="http://schemas.microsoft.com/ado/2006/04/edm"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;  &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;EntityContainer&lt;/span&gt; &lt;span class="attr"&gt;Name&lt;/span&gt;&lt;span class="kwrd"&gt;="Context"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;EntitySet&lt;/span&gt; &lt;span class="attr"&gt;Name&lt;/span&gt;&lt;span class="kwrd"&gt;="Client"&lt;/span&gt; &lt;span class="attr"&gt;EntityType&lt;/span&gt;&lt;span class="kwrd"&gt;="CustomModel.Client"&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;  &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;EntityContainer&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;  &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;EntityType&lt;/span&gt; &lt;span class="attr"&gt;Name&lt;/span&gt;&lt;span class="kwrd"&gt;="Client"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Key&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;      &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;PropertyRef&lt;/span&gt; &lt;span class="attr"&gt;Name&lt;/span&gt;&lt;span class="kwrd"&gt;="Id"&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Key&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Property&lt;/span&gt; &lt;span class="attr"&gt;Name&lt;/span&gt;&lt;span class="kwrd"&gt;="Id"&lt;/span&gt; &lt;span class="attr"&gt;Type&lt;/span&gt;&lt;span class="kwrd"&gt;="Int32"&lt;/span&gt; &lt;span class="attr"&gt;Nullable&lt;/span&gt;&lt;span class="kwrd"&gt;="false"&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Property&lt;/span&gt; &lt;span class="attr"&gt;Name&lt;/span&gt;&lt;span class="kwrd"&gt;="Nom"&lt;/span&gt; &lt;span class="attr"&gt;Type&lt;/span&gt;&lt;span class="kwrd"&gt;="String"&lt;/span&gt; &lt;span class="attr"&gt;MaxLength&lt;/span&gt;&lt;span class="kwrd"&gt;="50"&lt;/span&gt; &lt;span class="attr"&gt;Unicode&lt;/span&gt;&lt;span class="kwrd"&gt;="false"&lt;/span&gt; &lt;span class="attr"&gt;FixedLength&lt;/span&gt;&lt;span class="kwrd"&gt;="false"&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Property&lt;/span&gt; &lt;span class="attr"&gt;Name&lt;/span&gt;&lt;span class="kwrd"&gt;="Prenom"&lt;/span&gt; &lt;span class="attr"&gt;Type&lt;/span&gt;&lt;span class="kwrd"&gt;="String"&lt;/span&gt; &lt;span class="attr"&gt;MaxLength&lt;/span&gt;&lt;span class="kwrd"&gt;="50"&lt;/span&gt; &lt;span class="attr"&gt;Unicode&lt;/span&gt;&lt;span class="kwrd"&gt;="false"&lt;/span&gt; &lt;span class="attr"&gt;FixedLength&lt;/span&gt;&lt;span class="kwrd"&gt;="false"&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Property&lt;/span&gt; &lt;span class="attr"&gt;Name&lt;/span&gt;&lt;span class="kwrd"&gt;="Telephone"&lt;/span&gt; &lt;span class="attr"&gt;Type&lt;/span&gt;&lt;span class="kwrd"&gt;="String"&lt;/span&gt; &lt;span class="attr"&gt;MaxLength&lt;/span&gt;&lt;span class="kwrd"&gt;="10"&lt;/span&gt; &lt;span class="attr"&gt;Unicode&lt;/span&gt;&lt;span class="kwrd"&gt;="false"&lt;/span&gt; &lt;span class="attr"&gt;FixedLength&lt;/span&gt;&lt;span class="kwrd"&gt;="true"&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Property&lt;/span&gt; &lt;span class="attr"&gt;Name&lt;/span&gt;&lt;span class="kwrd"&gt;="Adresse"&lt;/span&gt; &lt;span class="attr"&gt;Type&lt;/span&gt;&lt;span class="kwrd"&gt;="Self.Adresse"&lt;/span&gt; &lt;span class="attr"&gt;Nullable&lt;/span&gt;&lt;span class="kwrd"&gt;="false"&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;  &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;EntityType&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;  &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;ComplexType&lt;/span&gt; &lt;span class="attr"&gt;Name&lt;/span&gt;&lt;span class="kwrd"&gt;="Adresse"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Property&lt;/span&gt; &lt;span class="attr"&gt;Name&lt;/span&gt;&lt;span class="kwrd"&gt;="Pays"&lt;/span&gt; &lt;span class="attr"&gt;Type&lt;/span&gt;&lt;span class="kwrd"&gt;="String"&lt;/span&gt; &lt;span class="attr"&gt;MaxLength&lt;/span&gt;&lt;span class="kwrd"&gt;="50"&lt;/span&gt; &lt;span class="attr"&gt;Unicode&lt;/span&gt;&lt;span class="kwrd"&gt;="false"&lt;/span&gt; &lt;span class="attr"&gt;FixedLength&lt;/span&gt;&lt;span class="kwrd"&gt;="false"&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Property&lt;/span&gt; &lt;span class="attr"&gt;Name&lt;/span&gt;&lt;span class="kwrd"&gt;="Rue"&lt;/span&gt; &lt;span class="attr"&gt;Type&lt;/span&gt;&lt;span class="kwrd"&gt;="String"&lt;/span&gt; &lt;span class="attr"&gt;MaxLength&lt;/span&gt;&lt;span class="kwrd"&gt;="100"&lt;/span&gt; &lt;span class="attr"&gt;Unicode&lt;/span&gt;&lt;span class="kwrd"&gt;="false"&lt;/span&gt; &lt;span class="attr"&gt;FixedLength&lt;/span&gt;&lt;span class="kwrd"&gt;="false"&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Property&lt;/span&gt; &lt;span class="attr"&gt;Name&lt;/span&gt;&lt;span class="kwrd"&gt;="CodePostal"&lt;/span&gt; &lt;span class="attr"&gt;Type&lt;/span&gt;&lt;span class="kwrd"&gt;="String"&lt;/span&gt; &lt;span class="attr"&gt;MaxLength&lt;/span&gt;&lt;span class="kwrd"&gt;="5"&lt;/span&gt; &lt;span class="attr"&gt;Unicode&lt;/span&gt;&lt;span class="kwrd"&gt;="false"&lt;/span&gt; &lt;span class="attr"&gt;FixedLength&lt;/span&gt;&lt;span class="kwrd"&gt;="true"&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Property&lt;/span&gt; &lt;span class="attr"&gt;Name&lt;/span&gt;&lt;span class="kwrd"&gt;="Ville"&lt;/span&gt; &lt;span class="attr"&gt;Type&lt;/span&gt;&lt;span class="kwrd"&gt;="String"&lt;/span&gt; &lt;span class="attr"&gt;MaxLength&lt;/span&gt;&lt;span class="kwrd"&gt;="50"&lt;/span&gt; &lt;span class="attr"&gt;Unicode&lt;/span&gt;&lt;span class="kwrd"&gt;="false"&lt;/span&gt; &lt;span class="attr"&gt;FixedLength&lt;/span&gt;&lt;span class="kwrd"&gt;="false"&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;  &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;ComplexType&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Schema&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;Il comporte la définition de l'entité Client comprenant entre autre une propriété Adresse faisant référence au type complexe CustomModel.Adresse. Celui-ci est composé de 4 propriétés (Pays, Rue, CodePostal, Ville).&lt;br /&gt;&lt;br /&gt;Pour finir, voici le schéma de liaison (MSL) :&lt;br /&gt;&lt;div class="csharpcode"&gt;&lt;br /&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Mapping&lt;/span&gt; &lt;span class="attr"&gt;Space&lt;/span&gt;&lt;span class="kwrd"&gt;="C-S"&lt;/span&gt; &lt;span class="attr"&gt;xmlns&lt;/span&gt;&lt;span class="kwrd"&gt;="urn:schemas-microsoft-com:windows:storage:mapping:CS"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;  &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;EntityContainerMapping&lt;/span&gt; &lt;span class="attr"&gt;StorageEntityContainer&lt;/span&gt;&lt;span class="kwrd"&gt;="CustomModelStoreContainer"&lt;/span&gt; &lt;span class="attr"&gt;CdmEntityContainer&lt;/span&gt;&lt;span class="kwrd"&gt;="Context"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;EntitySetMapping&lt;/span&gt; &lt;span class="attr"&gt;Name&lt;/span&gt;&lt;span class="kwrd"&gt;="Client"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;      &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;EntityTypeMapping&lt;/span&gt; &lt;span class="attr"&gt;TypeName&lt;/span&gt;&lt;span class="kwrd"&gt;="CustomModel.Client"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;MappingFragment&lt;/span&gt; &lt;span class="attr"&gt;StoreEntitySet&lt;/span&gt;&lt;span class="kwrd"&gt;="Client"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;          &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;ScalarProperty&lt;/span&gt; &lt;span class="attr"&gt;Name&lt;/span&gt;&lt;span class="kwrd"&gt;="Id"&lt;/span&gt; &lt;span class="attr"&gt;ColumnName&lt;/span&gt;&lt;span class="kwrd"&gt;="Id"&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;          &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;ScalarProperty&lt;/span&gt; &lt;span class="attr"&gt;Name&lt;/span&gt;&lt;span class="kwrd"&gt;="Nom"&lt;/span&gt; &lt;span class="attr"&gt;ColumnName&lt;/span&gt;&lt;span class="kwrd"&gt;="Nom"&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;          &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;ScalarProperty&lt;/span&gt; &lt;span class="attr"&gt;Name&lt;/span&gt;&lt;span class="kwrd"&gt;="Prenom"&lt;/span&gt; &lt;span class="attr"&gt;ColumnName&lt;/span&gt;&lt;span class="kwrd"&gt;="Prenom"&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;          &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;ScalarProperty&lt;/span&gt; &lt;span class="attr"&gt;Name&lt;/span&gt;&lt;span class="kwrd"&gt;="Telephone"&lt;/span&gt; &lt;span class="attr"&gt;ColumnName&lt;/span&gt;&lt;span class="kwrd"&gt;="Telephone"&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;          &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;ComplexProperty&lt;/span&gt; &lt;span class="attr"&gt;Name&lt;/span&gt;&lt;span class="kwrd"&gt;="Adresse"&lt;/span&gt; &lt;span class="attr"&gt;TypeName&lt;/span&gt;&lt;span class="kwrd"&gt;="CustomModel.Adresse"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;            &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;ScalarProperty&lt;/span&gt; &lt;span class="attr"&gt;Name&lt;/span&gt;&lt;span class="kwrd"&gt;="Pays"&lt;/span&gt; &lt;span class="attr"&gt;ColumnName&lt;/span&gt;&lt;span class="kwrd"&gt;="Pays"&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;            &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;ScalarProperty&lt;/span&gt; &lt;span class="attr"&gt;Name&lt;/span&gt;&lt;span class="kwrd"&gt;="Rue"&lt;/span&gt; &lt;span class="attr"&gt;ColumnName&lt;/span&gt;&lt;span class="kwrd"&gt;="Rue"&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;            &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;ScalarProperty&lt;/span&gt; &lt;span class="attr"&gt;Name&lt;/span&gt;&lt;span class="kwrd"&gt;="CodePostal"&lt;/span&gt; &lt;span class="attr"&gt;ColumnName&lt;/span&gt;&lt;span class="kwrd"&gt;="CodePostal"&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;            &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;ScalarProperty&lt;/span&gt; &lt;span class="attr"&gt;Name&lt;/span&gt;&lt;span class="kwrd"&gt;="Ville"&lt;/span&gt; &lt;span class="attr"&gt;ColumnName&lt;/span&gt;&lt;span class="kwrd"&gt;="Ville"&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;          &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;ComplexProperty&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;        &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;MappingFragment&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;      &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;EntityTypeMapping&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;EntitySetMapping&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;  &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;EntityContainerMapping&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Mapping&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;On y remarque le mapping entre l'entité Client et la table Client, ainsi qu'entre le type complexe CustomModel.Adresse et la table Client.&lt;br /&gt;&lt;br /&gt;Passons maintenant à la définition des classes et du contexte. 2 choix sont possibles, soit :&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Utiliser le custom tool fourni par Visual Studio 2008 ou l'outil "edmgen.exe" pour générer les classes et le contexte à partir du fichier CSDL.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Définir/Modifier à la main vos propres classes d'entité. Cette méthode est utile lorsque vous possédez déjà vos classes métier. Cela consiste à implémenter pour chaque entité les interfaces IPOCO d'Entity Framework et d'ajouter quelques attributs.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Pour faire simple, voici la démarche pour utiliser le Custom Tool "EntityModelCodeGenerator" :&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Sélectionnez le schéma conceptuel (fichier CSDL) dans Visual Studio.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Dans la fenêtre de propriétés, définissez la propriété Custom Tool à "EntityModelCodeGenerator".&lt;/li&gt;&lt;br /&gt;&lt;li&gt;A chaque sauvegarde du fichier CSDL, un fichier contenant les classes d'entité et le contexte est généré.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Et voila, si tout s'est bien passé, Client possède maintenant une variable de type Adresse, qui est notre type complexe.&lt;br /&gt;&lt;br /&gt;Vous trouverez dans l'archive ci-dessous le code source de l'article et les scripts SQL Serveur 2005 de la base de données.&lt;br /&gt;&lt;iframe scrolling="no" marginheight="0" marginwidth="0" frameborder="0" style="width:240px;height:66px;margin:3px;padding:0;border:1px solid #dde5e9;background-color:#ffffff;" src="http://cid-0d8992a88690ff41.skydrive.live.com/embedrowdetail.aspx/Public/blog/Types%20complexes.rar"&gt;&lt;/iframe&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3773144983876508185-1973361049942996327?l=populnet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://populnet.blogspot.com/feeds/1973361049942996327/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3773144983876508185&amp;postID=1973361049942996327' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3773144983876508185/posts/default/1973361049942996327'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3773144983876508185/posts/default/1973361049942996327'/><link rel='alternate' type='text/html' href='http://populnet.blogspot.com/2009/01/entity-framework-et-les-types-complexes.html' title='Entity Framework et les types complexes'/><author><name>Popul</name><uri>http://www.blogger.com/profile/13339110117970769017</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://2.bp.blogspot.com/__831xq1hNEM/SXSGahZtTOI/AAAAAAAAAC0/YTZpJgy1wUI/S220/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3773144983876508185.post-8751074217041559697</id><published>2009-01-22T22:50:00.004+01:00</published><updated>2009-01-22T23:03:35.230+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><title type='text'>Différentes façons de créer dynamiquement une méthode (3/3)</title><content type='html'>Ce billet es t le 3ème et dernier de la &lt;a href="http://populnet.blogspot.com/2009/01/diffrentes-faons-de-crer-dynamiquement.html"&gt;série&lt;/a&gt;. Tout comme les 2 précédents, il traite de la création dynamique d'une méthode et de son exécution.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;&lt;span style="font-size:130%;"&gt;Avec Mono.Cecil :&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Tout d'abord, qu'est ce que &lt;a href="http://www.mono-project.com/Main_Page"&gt;Mono&lt;/a&gt; ? C'est un projet Open-Source supporté par Novell. Celui-ci a pour but de fournir une machine virtuelle, les compilateurs C# 3.0 et VB.Net (il doit y en avoir d'autres) et supporte notamment Silverlight (projet MoonLight). Mono.Cecil est un sous projet de Mono et propose à peu près les mêmes fonctionnalités que les classes des espaces de nom System.Reflection et System.Reflection.Emit.&lt;br /&gt;&lt;br /&gt;D'une manière générale, Mono.Cecil est plus performant que son homologue et offre plus de possibilités. Patrick Smacchia a écrit un &lt;a href="http://codebetter.com/blogs/patricksmacchia/archive/2008/03/18/mono-cecil-vs-system-reflection.aspx"&gt;billet&lt;/a&gt; à ce sujet si cela vous intéresse.&lt;br /&gt;&lt;br /&gt;Comparé au billet précédent, l'utilisation de Mono.Cecil, pour générer et exécuter dynamiquement une méthode, est sensiblement pareille. Il y a cependant quelques exceptions :&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Je n'ai pas réussi à utiliser directement la méthode générée. J'ai du créer un assemblage à partir de la définition de l'assemblage modifié. Il doit être possible de faire autrement, mais je n'ai pas trouvé comment …&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Mono.Cecil fait bien la distinction entre les TypeDef et le TypeRef (c'est un sujet un peu avancé j'avoue, même pour moi …). En gros, un TypeDef (définition de type) contient toutes les métadonnées pour un type donné, comme par exemple sa classe mère, les interfaces implémentées, les méthodes et les propriétés qui le composent, etc … Un typeRef (référence à un type) contient uniquement le nom du type et une variable faisant référence à l'assemblage/module auquel il appartient. Du coup, avec l'espace de nom System.Reflection, il se peut qu'on obtienne parfois des exceptions car on utilise sans le savoir un TypeRef alors qu'il faudrait un TypeDef …&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Voici donc le code définissant et exécutant la méthode créée dynamiquement :&lt;br /&gt;&lt;div class="csharpcode"&gt;&lt;br /&gt;&lt;pre class="alt"&gt;var defAssembly = AssemblyFactory.GetAssembly(Assembly.GetExecutingAssembly().Location);&lt;/pre&gt;&lt;pre&gt;addGeneratedMethod(defAssembly);&lt;/pre&gt;&lt;pre class="alt"&gt;var modifiedAssembly = AssemblyFactory.CreateReflectionAssembly(defAssembly);&lt;/pre&gt;&lt;pre&gt;var modifiedType = modifiedAssembly.GetType(&lt;span class="str"&gt;"DynamicIL.Program"&lt;/span&gt;);&lt;/pre&gt;&lt;pre class="alt"&gt;modifiedType.GetMethod(&lt;span class="str"&gt;"helloCecil"&lt;/span&gt;).Invoke(&lt;span class="kwrd"&gt;null&lt;/span&gt;, &lt;span class="kwrd"&gt;null&lt;/span&gt;);&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Voilà l'explication de chaque instruction :&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Premièrement, on récupère une définition de l'assemblage.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;On fait appel à la méthode addGeneratedMethod qui créé et ajoute une méthode statique au type de la classe contenant la méthode Main. Son implémentation est expliquée juste après.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Un assemblage est créé à partir de la définition de l'assemblage modifié.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;On récupère le type de la classe DynamicIL.Program?.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;La méthode générée est appelée.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Voyons maintenant le corps de la méthode addGeneratedMethod :&lt;br /&gt;&lt;div class="csharpcode"&gt;&lt;br /&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; addGeneratedMethod(AssemblyDefinition pAssembly)&lt;/pre&gt;&lt;pre&gt;{&lt;/pre&gt;&lt;pre class="alt"&gt;    var type = pAssembly.MainModule.Types.Cast&amp;lt;TypeDefinition&amp;gt;().Where(typeDef =&amp;gt; typeDef.Name == &lt;span class="str"&gt;"Program"&lt;/span&gt;).First();&lt;/pre&gt;&lt;pre&gt;    var methodAttributes = Mono.Cecil.MethodAttributes.Public  Mono.Cecil.MethodAttributes.Static; &lt;/pre&gt;&lt;pre&gt;    TypeReference voidType = pAssembly.MainModule.Import(&lt;span class="kwrd"&gt;typeof&lt;/span&gt;(&lt;span class="kwrd"&gt;void&lt;/span&gt;));&lt;/pre&gt;&lt;pre class="alt"&gt;    MethodDefinition methodDef = &lt;span class="kwrd"&gt;new&lt;/span&gt; MethodDefinition(&lt;span class="str"&gt;"helloCecil"&lt;/span&gt;, methodAttributes, voidType);&lt;br /&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;    MethodInfo methodInfo = &lt;span class="kwrd"&gt;typeof&lt;/span&gt;(System.Console).GetMethod(&lt;span class="str"&gt;"WriteLine"&lt;/span&gt;, &lt;span class="kwrd"&gt;new&lt;/span&gt; Type[] { &lt;span class="kwrd"&gt;typeof&lt;/span&gt;(&lt;span class="kwrd"&gt;string&lt;/span&gt;) });&lt;/pre&gt;&lt;pre&gt;    var methodRef = pAssembly.MainModule.Import(methodInfo);&lt;/pre&gt;&lt;br /&gt;&lt;pre&gt;    CilWorker cilWorker = methodDef.Body.CilWorker;&lt;/pre&gt;&lt;pre class="alt"&gt;    cilWorker.Emit(Mono.Cecil.Cil.OpCodes.Ldstr, &lt;span class="str"&gt;"Hello World avec Mono.Cecil !"&lt;/span&gt;);&lt;/pre&gt;&lt;pre&gt;    cilWorker.Emit(Mono.Cecil.Cil.OpCodes.Call,methodRef);&lt;/pre&gt;&lt;pre class="alt"&gt;    cilWorker.Emit(Mono.Cecil.Cil.OpCodes.Ret);&lt;/pre&gt;&lt;pre&gt; &lt;/pre&gt;&lt;pre class="alt"&gt;    type.Methods.Add(methodDef);&lt;/pre&gt;&lt;pre&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Voici le détail de l'implémentation de la méthode:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;On récupère la définition du type Program.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Une énumératoin Mono.Cecil.MethodAttributes est assignée pour que la méthode générée soit publique et statique.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Une référence au type void est récupérée. Celle-ci sert aussi à la création de la méthode statique.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Via une instance de la classe MethodDefinition, on définie la signature de la méthode. Celle-ci s'appelle helloCecil, elle est publique ainsi que statique et renvoie un type void (c'est-à-dire rien).&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Les 2 instructions suivantes servent à récupérer une référence à la méthode WriteLine de la classe Console prenant une chaine de caractère en paramètre.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Les 4 instructions d'après permettent de définir le corps de la méthode de la méthode avec des instructions MSIL. Celles-ci sont équivalentes à celles utilisées dans &lt;a href="http://populnet.blogspot.com/2009/01/diffrentes-faons-de-crer-dynamiquement_22.html"&gt;l'exemple précédent&lt;/a&gt;.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Finalement, la définition de la méthode est ajoutée à la définition du type "Program".&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;A l'exécution du programme, vous devriez voire apparaître à l'écran "Hello World avec Mono.Cecil !".&lt;br /&gt;&lt;br /&gt;Pour plus d'informations, l'archive ci-dessous reprend le code des 3 méthodes de génération dynamique présentées.&lt;br /&gt;&lt;iframe scrolling="no" marginheight="0" marginwidth="0" frameborder="0" style="width:240px;height:66px;margin:3px;padding:0;border:1px solid #dde5e9;background-color:#ffffff;" src="http://cid-0d8992a88690ff41.skydrive.live.com/embedrowdetail.aspx/Public/blog/DynamicIL.rar"&gt;&lt;/iframe&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3773144983876508185-8751074217041559697?l=populnet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://populnet.blogspot.com/feeds/8751074217041559697/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3773144983876508185&amp;postID=8751074217041559697' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3773144983876508185/posts/default/8751074217041559697'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3773144983876508185/posts/default/8751074217041559697'/><link rel='alternate' type='text/html' href='http://populnet.blogspot.com/2009/01/diffrentes-faons-de-crer-dynamiquement_5630.html' title='Différentes façons de créer dynamiquement une méthode (3/3)'/><author><name>Popul</name><uri>http://www.blogger.com/profile/13339110117970769017</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://2.bp.blogspot.com/__831xq1hNEM/SXSGahZtTOI/AAAAAAAAAC0/YTZpJgy1wUI/S220/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3773144983876508185.post-3220845562855695363</id><published>2009-01-22T15:59:00.004+01:00</published><updated>2009-01-22T23:04:14.348+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><title type='text'>Différentes façons de créer dynamiquement une méthode (2/3)</title><content type='html'>Ce billet est le 2ème de la &lt;a href="http://populnet.blogspot.com/2009/01/diffrentes-faons-de-crer-dynamiquement.html"&gt;série&lt;/a&gt;. Il traite de la création dynamique d'une méthode.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;strong&gt;Avec l'espace de nom System.Reflection.Emit :&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Alors que l'espace de nom System.Reflection contient les classes nécessaires pour interroger la structure du code en .Net, l'espace de nom System.Reflection.Emit permet de modifier dynamiquement les différents éléments (classes, structures, énumérations, etc …) du langage.&lt;br /&gt;&lt;br /&gt;Pour ce qui concerne la génération d'une méthode à l'exécution, cela se fait simplement avec la classe System.Reflection.Emit.DynamicMethod ,tout du moins pour la déclaration de la méthode. Ensuite, et c'est là où ça devient un peu plus compliqué, il faut rajouter les instructions composant le corps de la méthode en injectant des instructions &lt;a href="http://fr.wikipedia.org/wiki/Common_Intermediate_Language"&gt;MSIL&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;MSIL pour MicroSoft Intermediate Language ou CIL (Common Intermediate Language) est le langage intermédiaire utilisé par la machine virtuelle du Framework .Net. Celui-ci est ensuite compilé pour pouvoir être exécuté sur la machine hôte. En fait, les compilateurs de la plateforme .Net, comme celui du C# ou de VB .Net transforment le code produit par le développeur en langage MSIL.&lt;br /&gt;&lt;br /&gt;Vous trouverez un tutorial en anglais sur le MSIL à l'adresse suivante : http://weblogs.asp.net/kennykerr/archive/2004/09/07/introduction-to-msil-part-1-hello-world.aspx. Comparé à un langage comme l'assembleur, le MSIL est orienté objet et adopte la notion de piles.&lt;br /&gt;&lt;br /&gt;Je vous rassure, je ne suis pas du tout un expert en MSIL, enfin pas encore ! Pour m'y retrouver, j'utilise Reflector qui permet de décompiler un assemblage .Net et de voir le code MSIL produit. En comparant avec le code C# ou VB.Net, il est possible de s'y retrouver.&lt;br /&gt;&lt;br /&gt;Passons maintenant au code, voici les instructions définissant notre méthode, faisant appel à une procédure définissant le corps de la méthode, un délégué est ensuite créé et assigné, et finalement celui-ci est appelé.&lt;br /&gt;&lt;div class="csharpcode"&gt;&lt;br /&gt;&lt;pre class="alt"&gt;DynamicMethod dynMeth = &lt;span class="kwrd"&gt;new&lt;/span&gt; DynamicMethod(&lt;span class="str"&gt;"foo"&lt;/span&gt;, &lt;span class="kwrd"&gt;typeof&lt;/span&gt;(&lt;span class="kwrd"&gt;void&lt;/span&gt;), &lt;span class="kwrd"&gt;null&lt;/span&gt;, &lt;span class="kwrd"&gt;typeof&lt;/span&gt;(Program));&lt;/pre&gt;&lt;pre&gt;WriteHello(dynMeth.GetILGenerator());&lt;/pre&gt;&lt;pre class="alt"&gt;Method meth1 = (Method)dynMeth.CreateDelegate(&lt;span class="kwrd"&gt;typeof&lt;/span&gt;(Method));&lt;/pre&gt;&lt;pre&gt;meth1();&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Le constructeur de DynamicMethod utilisé prend en paramètre:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Le nom de la méthode : "foo"&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Le type renvoyé : typeof(void)&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Un tableau de Type définissant les types des arguments de la méthode : null (notre méthode ne prend aucun argument)&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Le type qui reçoit cette nouvelle méthode : typeof(Program). Pour l'exemple, c'est le nom de la classe contenant la méthode statique main.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Voici maintenant le corps de la procédure WriteHello(ILGenerator) qui définit le corps de la méthode générée :&lt;br /&gt;&lt;div class="csharpcode"&gt;&lt;br /&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; WriteHello(ILGenerator cg)&lt;/pre&gt;&lt;pre&gt;{&lt;/pre&gt;&lt;pre class="alt"&gt;    cg.Emit(System.Reflection.Emit.OpCodes.Ldstr, &lt;span class="str"&gt;"Hello World avec System.Reflection.Emit !"&lt;/span&gt;);&lt;/pre&gt;&lt;pre&gt;    cg.Emit(System.Reflection.Emit.OpCodes.Call,&lt;/pre&gt;&lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;typeof&lt;/span&gt;(System.Console).GetMethod(&lt;span class="str"&gt;"WriteLine"&lt;/span&gt;,&lt;/pre&gt;&lt;pre&gt;    &lt;span class="kwrd"&gt;new&lt;/span&gt; Type[] { &lt;span class="kwrd"&gt;typeof&lt;/span&gt;(&lt;span class="kwrd"&gt;string&lt;/span&gt;) }));&lt;/pre&gt;&lt;pre class="alt"&gt;    cg.Emit(System.Reflection.Emit.OpCodes.Ret);&lt;/pre&gt;&lt;pre&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Premièrement, on ajoute sur la pile la chaine de caractères "Hello World avec System.Reflection.Emit !". En MSIL, il est obligatoire de faire cela pour utiliser une constante. La 2ème instruction fait un appel à la méthode statique Console.WriteLine prenant en argument une chaine de caractère. La chaine de caractère utilisée est celle qui est en haut de la pile, c'est dire "Hello World avec System.Reflection.Emit !". La dernière instruction signifie la fin du corps de la méthode (ceci correspond à return;).&lt;br /&gt;&lt;br /&gt;Après compilation, vous devriez voir apparaître dans la console "Hello World avec System.Reflection.Emit !". C'est magique non ?!&lt;br /&gt;&lt;br /&gt;Pour plus d'informations, l'archive ci-dessous reprend le code des 3 méthodes de génération dynamique présentées.&lt;br /&gt;&lt;iframe scrolling="no" marginheight="0" marginwidth="0" frameborder="0" style="width:240px;height:66px;margin:3px;padding:0;border:1px solid #dde5e9;background-color:#ffffff;" src="http://cid-0d8992a88690ff41.skydrive.live.com/embedrowdetail.aspx/Public/blog/DynamicIL.rar"&gt;&lt;/iframe&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3773144983876508185-3220845562855695363?l=populnet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://populnet.blogspot.com/feeds/3220845562855695363/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3773144983876508185&amp;postID=3220845562855695363' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3773144983876508185/posts/default/3220845562855695363'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3773144983876508185/posts/default/3220845562855695363'/><link rel='alternate' type='text/html' href='http://populnet.blogspot.com/2009/01/diffrentes-faons-de-crer-dynamiquement_22.html' title='Différentes façons de créer dynamiquement une méthode (2/3)'/><author><name>Popul</name><uri>http://www.blogger.com/profile/13339110117970769017</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://2.bp.blogspot.com/__831xq1hNEM/SXSGahZtTOI/AAAAAAAAAC0/YTZpJgy1wUI/S220/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3773144983876508185.post-5642862575234602403</id><published>2009-01-22T13:26:00.017+01:00</published><updated>2009-01-22T23:04:34.835+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><title type='text'>Différentes façons de créer dynamiquement une méthode (1/3)</title><content type='html'>&lt;a href="http://populnet.blogspot.com/2008/12/excuter-une-chaine-de-caractre.html"&gt;Dernièrement&lt;/a&gt;, j'avais cherché à créer une méthode grâce à l'API CodeDom, de générer/compiler un assemblage, de le charger en mémoire et enfin d'exécuter la méthode générée.&lt;br /&gt;&lt;br /&gt;Cette méthode fonctionne, cependant elle a l'inconvénient de passer par une compilation du C# en MSIL avant de pouvoir enfin exécuter la méthode générée.&lt;br /&gt;Je me suis demandé alors si c'était possible de générer et d'injecter dynamiquement une méthode dans l'assemblage utilisé ou ailleurs et de l'exécuter par la suite. En cherchant sur la toile, je suis tombé sur 4 solutions abordables :&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;Utiliser les classes de l'espace de nom &lt;a href="http://msdn.microsoft.com/en-us/library/system.reflection.emit.aspx"&gt;System.Reflection.Emit&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Utiliser les &lt;a href="http://msdn.microsoft.com/en-us/library/bb882636.aspx"&gt;arbres d'expressions de LinQ&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Utiliser &lt;a href="http://www.mono-project.com/Cecil"&gt;Mono.Cecil&lt;/a&gt; qui est un projet open source.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Utiliser l'API bas niveau de &lt;a href="http://www.postsharp.org/"&gt;PostSharp.&lt;/a&gt; C'est un framework de &lt;a href="http://fr.wikipedia.org/wiki/Programmation_orient%C3%A9e_aspect"&gt;programmation orientée aspect&lt;/a&gt;.&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;J'ai donc mis en œuvre les 3 premières solutions, c'est-à-dire une implémentation avec System.Reflection.Emit, les arbres d'expressions et Mono.Cecil. Concernant PostSharp, je pense que je m'y pencherai un autre jour.&lt;br /&gt;&lt;br /&gt;Pour information, chaque méthode générée est un simple Hello World affichée dans la console.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;strong&gt;Avec les arbres d'expressions&lt;/strong&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;Commençons par l'implémentation la plus facile, celle utilisant les arbres d'expressions. Succinctement, un arbre d'expressions est une structure de données représentant du code. Il est ensuite possible de générer une méthode dynamiquement. Dans LinQ , les arbres d'expressions sont utilisés avec l'interface IQueryable&lt;t&gt; et le type générique Expression&lt;t&gt;. Ce dernier est toujours associé à des expressions lambdas, qui ne sont rien d'autres que des méthodes anonymes composée d'une seule instruction (comprenez un seul point-virgule ;). Ensuite le compilateur C# ou VB.Net transforme l'expression lambda en un arbre d'expression.&lt;br /&gt;&lt;br /&gt;Pour information, LinQ to SQL et LinQ to Entities utilisent les arbres d'expressions pour transformer une expression lambda (condition dans un méthode Where par exemple) en SQL.&lt;br /&gt;&lt;br /&gt;L'instruction suivante :&lt;br /&gt;&lt;div class="csharpcode"&gt;&lt;br /&gt;&lt;pre class="alt"&gt;Expression&amp;lt;Action&amp;gt; expr = () =&amp;gt; Console.WriteLine(&lt;span class="str"&gt;"Hello World avec les arbres d'expression !"&lt;/span&gt;);&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;Donne après décompilation avec &lt;a href="http://www.red-gate.com/products/reflector/"&gt;Reflector&lt;/a&gt; :&lt;br /&gt;&lt;div class="csharpcode"&gt;&lt;br /&gt;&lt;pre class="alt"&gt;Expression&amp;lt;Action&amp;gt; expr = Expression.Lambda&amp;lt;Action&amp;gt;(&lt;/pre&gt;&lt;pre&gt;                                    Expression.Call(&lt;span class="kwrd"&gt;null&lt;/span&gt;, &lt;/pre&gt;&lt;pre class="alt"&gt;                                                    &lt;span class="kwrd"&gt;typeof&lt;/span&gt;(System.Console).GetMethod(&lt;span class="str"&gt;"WriteLine"&lt;/span&gt;, &lt;span class="kwrd"&gt;new&lt;/span&gt; Type[] { &lt;span class="kwrd"&gt;typeof&lt;/span&gt;(&lt;span class="kwrd"&gt;string&lt;/span&gt;) }), &lt;/pre&gt;&lt;pre&gt;                                                    &lt;span class="kwrd"&gt;new&lt;/span&gt; Expression[] { Expression.Constant(&lt;span class="str"&gt;"Hello World avec les arbres d'expression !"&lt;/span&gt;, &lt;span class="kwrd"&gt;typeof&lt;/span&gt;(&lt;span class="kwrd"&gt;string&lt;/span&gt;)) }), &lt;/pre&gt;&lt;pre class="alt"&gt;                                    &lt;span class="kwrd"&gt;new&lt;/span&gt; ParameterExpression[0]);&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;On s'aperçoit que le compilateur C# a transformé notre expression lambda en un arbre d'expressions.&lt;br /&gt;Pour plus de détails sur les arbres d'expressions, voici le &lt;a href="http://msdn.microsoft.com/fr-fr/library/bb397951.aspx"&gt;lien&lt;/a&gt; MSDN.&lt;br /&gt;&lt;br /&gt;Voici donc le code pour générer notre HelloWorld de façon dynamique et avec les arbres d'expression :&lt;br /&gt;&lt;br /&gt;&lt;div class="csharpcode"&gt;&lt;br /&gt;&lt;pre class="alt"&gt;Expression&amp;lt;Action&amp;gt; expr = Expression.Lambda&amp;lt;Action&amp;gt;(&lt;/pre&gt;&lt;pre&gt;                                    Expression.Call(&lt;span class="kwrd"&gt;null&lt;/span&gt;, &lt;/pre&gt;&lt;pre class="alt"&gt;                                                    &lt;span class="kwrd"&gt;typeof&lt;/span&gt;(System.Console).GetMethod(&lt;span class="str"&gt;"WriteLine"&lt;/span&gt;, &lt;span class="kwrd"&gt;new&lt;/span&gt; Type[] { &lt;span class="kwrd"&gt;typeof&lt;/span&gt;(&lt;span class="kwrd"&gt;string&lt;/span&gt;) }), &lt;/pre&gt;&lt;pre&gt;                                                    &lt;span class="kwrd"&gt;new&lt;/span&gt; Expression[] { Expression.Constant(&lt;span class="str"&gt;"Hello World avec les arbres d'expression !"&lt;/span&gt;, &lt;span class="kwrd"&gt;typeof&lt;/span&gt;(&lt;span class="kwrd"&gt;string&lt;/span&gt;)) }), &lt;/pre&gt;&lt;pre class="alt"&gt;                                    &lt;span class="kwrd"&gt;new&lt;/span&gt; ParameterExpression[0]);&lt;/pre&gt;&lt;pre class="alt"&gt;var meth2 = expr.Compile();&lt;/pre&gt;&lt;pre&gt;meth2();&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;A la 1ère ligne, l'expression lambda est définie et assignée au type Expression&lt;action&gt;. Ce code une fois compilé résulte donc en un arbre d'expressions. En d'autres termes, Le compilateur C# a transformé la logique de l'expression lambda en données. Pour transformer ensuite l'arbre d'expressions en logique, il suffit simplement d'appeler la méthode Compile de la classe Expression&lt;t&gt; . Cette méthode retourne un délégué qui représente la méthode générée.&lt;br /&gt;&lt;br /&gt;Petite remarque, il est très facile de générer du code via les arbres d'expressions. Cependant, un arbre ne peut contenir que l'équivalent d'une instruction, tout comme les expressions lambdas. Du coup, pas besoin de connaitre le MSIL.&lt;br /&gt;&lt;br /&gt;Nous verrons dans le prochain billet comment générer une méthode avec les classes de l'espace de nom System.Reflection.Emit.&lt;br /&gt;&lt;br /&gt;Pour plus d'informations, l'archive ci-dessous reprend le code des 3 méthodes de génération dynamique présentées.&lt;br /&gt;&lt;iframe scrolling="no" marginheight="0" marginwidth="0" frameborder="0" style="width:240px;height:66px;margin:3px;padding:0;border:1px solid #dde5e9;background-color:#ffffff;" src="http://cid-0d8992a88690ff41.skydrive.live.com/embedrowdetail.aspx/Public/blog/DynamicIL.rar"&gt;&lt;/iframe&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3773144983876508185-5642862575234602403?l=populnet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://populnet.blogspot.com/feeds/5642862575234602403/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3773144983876508185&amp;postID=5642862575234602403' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3773144983876508185/posts/default/5642862575234602403'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3773144983876508185/posts/default/5642862575234602403'/><link rel='alternate' type='text/html' href='http://populnet.blogspot.com/2009/01/diffrentes-faons-de-crer-dynamiquement.html' title='Différentes façons de créer dynamiquement une méthode (1/3)'/><author><name>Popul</name><uri>http://www.blogger.com/profile/13339110117970769017</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://2.bp.blogspot.com/__831xq1hNEM/SXSGahZtTOI/AAAAAAAAAC0/YTZpJgy1wUI/S220/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3773144983876508185.post-8272356642915419921</id><published>2009-01-19T18:16:00.008+01:00</published><updated>2009-01-19T18:26:14.777+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><title type='text'>Générer un flux RSS avec LinQ To XML</title><content type='html'>LinQ To XML permet de manipuler les fichiers et les flux XML. C'est la dernière API XML de Microsoft et celle-ci offre l'avantage d'être beaucoup plus facile à utiliser que XmlTextReader/XmlTextWriter, grâce à son style fonctionnel.&lt;br /&gt;&lt;br /&gt;Dernièrement, j'ai du générer quelques flux RSS pour un projet Sharepoint. Je me suis donc servi de LinQ To XML pour créer les flux en question.&lt;br /&gt;&lt;br /&gt;Voici donc le code nécessaire pour générer un flux RSS avec LinQ To XML :&lt;br /&gt;&lt;br /&gt;&lt;div class="csharpcode"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; ItemRSS&lt;/pre&gt;&lt;/div&gt;&lt;div class="csharpcode"&gt;&lt;pre&gt;{&lt;/pre&gt;&lt;/div&gt;&lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; Titre { get; set; }&lt;/pre&gt;&lt;/div&gt;&lt;div class="csharpcode"&gt;&lt;pre&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; Lien { get; set; }&lt;/pre&gt;&lt;/div&gt;&lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; Description { get; set; }&lt;/pre&gt;&lt;/div&gt;&lt;div class="csharpcode"&gt;&lt;pre&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; Auteur { get; set; }&lt;/pre&gt;&lt;/div&gt;&lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; Date { get; set; }&lt;/pre&gt;&lt;/div&gt;&lt;div class="csharpcode"&gt;&lt;pre&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; Source { get; set; }&lt;/pre&gt;&lt;/div&gt;&lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; Catégorie { get; set; }&lt;/pre&gt;&lt;/div&gt;&lt;div class="csharpcode"&gt;&lt;pre&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; Guid { get; set; }&lt;/pre&gt;&lt;/div&gt;&lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;div class="csharpcode"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; BuildRSS(&lt;span class="kwrd"&gt;string&lt;/span&gt; pTitreRSS, &lt;/pre&gt;&lt;/div&gt;&lt;div class="csharpcode"&gt;&lt;pre&gt;                              &lt;span class="kwrd"&gt;string&lt;/span&gt; pLienRSS, &lt;/pre&gt;&lt;/div&gt;&lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt;                              &lt;span class="kwrd"&gt;string&lt;/span&gt; pDescription, &lt;/pre&gt;&lt;/div&gt;&lt;div class="csharpcode"&gt;&lt;pre&gt;                              &lt;span class="kwrd"&gt;string&lt;/span&gt; pLanguage,&lt;/pre&gt;&lt;/div&gt;&lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt;                              &lt;span class="kwrd"&gt;string&lt;/span&gt; pPubDate,&lt;/pre&gt;&lt;/div&gt;&lt;div class="csharpcode"&gt;&lt;pre&gt;                              &lt;span class="kwrd"&gt;string&lt;/span&gt; pDerniereDate,&lt;/pre&gt;&lt;/div&gt;&lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt;                              &lt;span class="kwrd"&gt;string&lt;/span&gt; pNomGenerateur,&lt;/pre&gt;&lt;/div&gt;&lt;div class="csharpcode"&gt;&lt;pre&gt;                              &lt;span class="kwrd"&gt;string&lt;/span&gt; pMailResponsable,&lt;/pre&gt;&lt;/div&gt;&lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt;                              IEnumerable&amp;lt;ItemRSS&amp;gt; pListeItems)&lt;/pre&gt;&lt;/div&gt;&lt;div class="csharpcode"&gt;&lt;pre&gt;{&lt;/pre&gt;&lt;/div&gt;&lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt;    XDocument xdoc = &lt;span class="kwrd"&gt;new&lt;/span&gt; XDocument(&lt;/pre&gt;&lt;/div&gt;&lt;div class="csharpcode"&gt;&lt;pre&gt;                        &lt;span class="kwrd"&gt;new&lt;/span&gt; XDeclaration(&lt;span class="str"&gt;"1.0"&lt;/span&gt;, &lt;span class="str"&gt;"UTF-8"&lt;/span&gt;, &lt;span class="str"&gt;"yes"&lt;/span&gt;),&lt;/pre&gt;&lt;/div&gt;&lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt;                        &lt;span class="kwrd"&gt;new&lt;/span&gt; XElement(&lt;span class="str"&gt;"rss"&lt;/span&gt;,&lt;/pre&gt;&lt;/div&gt;&lt;div class="csharpcode"&gt;&lt;pre&gt;                            &lt;span class="kwrd"&gt;new&lt;/span&gt; XElement(&lt;span class="str"&gt;"channel"&lt;/span&gt;,&lt;/pre&gt;&lt;/div&gt;&lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt;                                &lt;span class="kwrd"&gt;new&lt;/span&gt; XElement(&lt;span class="str"&gt;"title"&lt;/span&gt;, pTitreRSS),&lt;/pre&gt;&lt;/div&gt;&lt;div class="csharpcode"&gt;&lt;pre&gt;                                &lt;span class="kwrd"&gt;new&lt;/span&gt; XElement(&lt;span class="str"&gt;"link"&lt;/span&gt;, pLienRSS),&lt;/pre&gt;&lt;/div&gt;&lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt;                                &lt;span class="kwrd"&gt;new&lt;/span&gt; XElement(&lt;span class="str"&gt;"description"&lt;/span&gt;, pDescription),&lt;/pre&gt;&lt;/div&gt;&lt;div class="csharpcode"&gt;&lt;pre&gt;                                &lt;span class="kwrd"&gt;new&lt;/span&gt; XElement(&lt;span class="str"&gt;"language"&lt;/span&gt;, pLanguage),&lt;/pre&gt;&lt;/div&gt;&lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt;                                &lt;span class="kwrd"&gt;new&lt;/span&gt; XElement(&lt;span class="str"&gt;"pubDate"&lt;/span&gt;,pPubDate),&lt;/pre&gt;&lt;/div&gt;&lt;div class="csharpcode"&gt;&lt;pre&gt;                                &lt;span class="kwrd"&gt;new&lt;/span&gt; XElement(&lt;span class="str"&gt;"lastBuildDate"&lt;/span&gt;,pDerniereDate),&lt;/pre&gt;&lt;/div&gt;&lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt;                                &lt;span class="kwrd"&gt;new&lt;/span&gt; XElement(&lt;span class="str"&gt;"generator"&lt;/span&gt;, pNomGenerateur),&lt;/pre&gt;&lt;/div&gt;&lt;div class="csharpcode"&gt;&lt;pre&gt;                                &lt;span class="kwrd"&gt;new&lt;/span&gt; XElement(&lt;span class="str"&gt;"webMaster"&lt;/span&gt;,pMailResponsable),&lt;/pre&gt;&lt;/div&gt;&lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt;                                from item &lt;span class="kwrd"&gt;in&lt;/span&gt; pListeItems&lt;/pre&gt;&lt;/div&gt;&lt;div class="csharpcode"&gt;&lt;pre&gt;                                select &lt;span class="kwrd"&gt;new&lt;/span&gt; XElement(&lt;span class="str"&gt;"item"&lt;/span&gt;,&lt;/pre&gt;&lt;/div&gt;&lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt;                                    &lt;span class="kwrd"&gt;new&lt;/span&gt; XElement(&lt;span class="str"&gt;"title"&lt;/span&gt;, item.Titre),&lt;/pre&gt;&lt;/div&gt;&lt;div class="csharpcode"&gt;&lt;pre&gt;                                    &lt;span class="kwrd"&gt;new&lt;/span&gt; XElement(&lt;span class="str"&gt;"link"&lt;/span&gt;, item.Lien),&lt;/pre&gt;&lt;/div&gt;&lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt;                                    &lt;span class="kwrd"&gt;new&lt;/span&gt; XElement(&lt;span class="str"&gt;"description"&lt;/span&gt;, &lt;span class="kwrd"&gt;new&lt;/span&gt; XCData(item.Description)),&lt;/pre&gt;&lt;/div&gt;&lt;div class="csharpcode"&gt;&lt;pre&gt;                                    &lt;span class="kwrd"&gt;new&lt;/span&gt; XElement(&lt;span class="str"&gt;"author"&lt;/span&gt;, item.Auteur),&lt;/pre&gt;&lt;/div&gt;&lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt;                                    &lt;span class="kwrd"&gt;new&lt;/span&gt; XElement(&lt;span class="str"&gt;"pubDate"&lt;/span&gt;, item.Date),&lt;/pre&gt;&lt;/div&gt;&lt;div class="csharpcode"&gt;&lt;pre&gt;                                    &lt;span class="kwrd"&gt;new&lt;/span&gt; XElement(&lt;span class="str"&gt;"guid"&lt;/span&gt;, item.Lien),&lt;/pre&gt;&lt;/div&gt;&lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt;                                    &lt;span class="kwrd"&gt;new&lt;/span&gt; XElement(&lt;span class="str"&gt;"source"&lt;/span&gt;,item.Source),&lt;/pre&gt;&lt;/div&gt;&lt;div class="csharpcode"&gt;&lt;pre&gt;                                    &lt;span class="kwrd"&gt;new&lt;/span&gt; XElement(&lt;span class="str"&gt;"category"&lt;/span&gt;,item.Catégorie))),&lt;/pre&gt;&lt;/div&gt;&lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt;                            &lt;span class="kwrd"&gt;new&lt;/span&gt; XAttribute(&lt;span class="str"&gt;"version"&lt;/span&gt;, &lt;span class="str"&gt;"2.0"&lt;/span&gt;)));&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;return&lt;/span&gt; xdoc.ToString();&lt;/pre&gt;&lt;/div&gt;&lt;div class="csharpcode"&gt;&lt;pre&gt;}&lt;/pre&gt;&lt;pre&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;La classe ItemRSS représente un item du flux RSS et chaque propriété publique représente un élément de l'item.&lt;br /&gt;&lt;br /&gt;La méthode statique BuildRSS prend en paramètre quelques valeurs définissant les éléments enfants de l'élément channel d'un flux RSS et prend aussi en paramètre la liste des items contenus dans le flux RSS.&lt;br /&gt;&lt;br /&gt;En une seule instruction, celle du constructeur de la classe XDocument, la méthode BuildRSS construit l'intégralité du flux RSS. Un élément XML du style &amp;lt;title&amp;gt;titre&amp;lt;/title&amp;gt; est représenté par l'instruction suivante : new XElement("title","titre"). Une déclaration XML est représentée par la classe Xdeclaration et un attribut par XAttribute.&lt;br /&gt;&lt;br /&gt;Les classes XDocument et XElement peuvent aussi prendre en paramètre dans leur constructeur un tableau d'objets (params object[]), ce qui permet facilement de définir les enfants d'un élément XML.&lt;br /&gt;&lt;br /&gt;Vous trouverez ci-dessous un exemple d'application Console utilisant ce code pour générer un flux RSS (nécessite Visual Studio 2008).&lt;br /&gt;&lt;iframe style="BORDER-BOTTOM: #dde5e9 1px solid; BORDER-LEFT: #dde5e9 1px solid; PADDING-BOTTOM: 0px; BACKGROUND-COLOR: #ffffff; MARGIN: 3px; PADDING-LEFT: 0px; WIDTH: 240px; PADDING-RIGHT: 0px; HEIGHT: 66px; BORDER-TOP: #dde5e9 1px solid; BORDER-RIGHT: #dde5e9 1px solid; PADDING-TOP: 0px" marginheight="0" src="http://cid-0d8992a88690ff41.skydrive.live.com/embedrowdetail.aspx/Public/blog/RSSLinqToXML.rar" frameborder="0" marginwidth="0" scrolling="no"&gt;&lt;/iframe&gt;&lt;pre&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3773144983876508185-8272356642915419921?l=populnet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://populnet.blogspot.com/feeds/8272356642915419921/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3773144983876508185&amp;postID=8272356642915419921' title='1 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3773144983876508185/posts/default/8272356642915419921'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3773144983876508185/posts/default/8272356642915419921'/><link rel='alternate' type='text/html' href='http://populnet.blogspot.com/2009/01/gnrer-un-flux-rss-avec-linq-to-xml.html' title='Générer un flux RSS avec LinQ To XML'/><author><name>Popul</name><uri>http://www.blogger.com/profile/13339110117970769017</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://2.bp.blogspot.com/__831xq1hNEM/SXSGahZtTOI/AAAAAAAAAC0/YTZpJgy1wUI/S220/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3773144983876508185.post-2503282970598397408</id><published>2009-01-19T12:51:00.006+01:00</published><updated>2009-01-19T14:53:53.329+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><title type='text'>Récupérer la valeur d'une propriété d'un objet à partir de son nom</title><content type='html'>&lt;span xmlns=""&gt; &lt;p&gt;Si vous souhaitez récupérer la valeur d'une propriété ou d'une variable membre publique à partir de son nom, voici 2 méthodes utilitaires permettant de faire cela grâce à la réflexion :&lt;br /&gt;&lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;&lt;br /&gt;&lt;div class="csharpcode"&gt;&lt;br /&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;class&lt;/span&gt; Objet&lt;/pre&gt;&lt;pre&gt;{&lt;/pre&gt;&lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; Nom { get; set; }&lt;/pre&gt;&lt;pre&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; Variable;&lt;/pre&gt;&lt;pre class="alt"&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; Util&lt;/pre&gt;&lt;pre&gt;{&lt;/pre&gt;&lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; T GetValeurProp&amp;lt;T&amp;gt;(&lt;span class="kwrd"&gt;this&lt;/span&gt; &lt;span class="kwrd"&gt;object&lt;/span&gt; pObjet, &lt;span class="kwrd"&gt;string&lt;/span&gt; pNom)&lt;/pre&gt;&lt;pre&gt;    {&lt;/pre&gt;&lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;return&lt;/span&gt; (T)pObjet.GetType().GetProperty(pNom).GetValue(pObjet, &lt;span class="kwrd"&gt;null&lt;/span&gt;);&lt;/pre&gt;&lt;pre&gt;    }&lt;br /&gt;&lt;/pre&gt;&lt;pre&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; T GetValeurField&amp;lt;T&amp;gt;(&lt;span class="kwrd"&gt;this&lt;/span&gt; &lt;span class="kwrd"&gt;object&lt;/span&gt; pObjet, &lt;span class="kwrd"&gt;string&lt;/span&gt; pNom)&lt;/pre&gt;&lt;pre class="alt"&gt;    {&lt;/pre&gt;&lt;pre&gt;        &lt;span class="kwrd"&gt;return&lt;/span&gt; (T)pObjet.GetType().GetField(pNom).GetValue(pObjet);&lt;/pre&gt;&lt;pre class="alt"&gt;    }&lt;/pre&gt;&lt;pre&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;pre class="alt"&gt; &lt;/pre&gt;&lt;pre&gt;&lt;span class="kwrd"&gt;class&lt;/span&gt; Program&lt;/pre&gt;&lt;pre class="alt"&gt;{&lt;/pre&gt;&lt;pre&gt;    &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Main(&lt;span class="kwrd"&gt;string&lt;/span&gt;[] args)&lt;/pre&gt;&lt;pre class="alt"&gt;    {&lt;/pre&gt;&lt;pre&gt;        var obj = &lt;span class="kwrd"&gt;new&lt;/span&gt; Objet() { Nom = &lt;span class="str"&gt;"Propriété"&lt;/span&gt;, Variable = &lt;span class="str"&gt;"variable membre publique"&lt;/span&gt; };&lt;/pre&gt;&lt;pre&gt;        Console.WriteLine(obj.GetValeurProp&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt;(&lt;span class="str"&gt;"Nom"&lt;/span&gt;));&lt;/pre&gt;&lt;pre class="alt"&gt;        Console.WriteLine(obj.GetValeurField&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt;(&lt;span class="str"&gt;"Variable"&lt;/span&gt;));&lt;/pre&gt;&lt;pre&gt;        Console.ReadKey();&lt;/pre&gt;&lt;pre class="alt"&gt;    }&lt;/pre&gt;&lt;pre&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;/span&gt;&lt;span xmlns=""&gt;Grâce aux méthodes GetField(string) et GetProperty(string) de la classe &lt;em&gt;Type&lt;/em&gt;, il est possible de récupérer respectivement une variable membre publique et une propriété publique d'une classe à partir d'une chaine de caractères. Après il suffit simplement d'appeler la méthode &lt;em&gt;GetValue&lt;/em&gt; des objets &lt;em&gt;FieldInfo&lt;/em&gt; et &lt;em&gt;PropertyInfo&lt;/em&gt; pour récupérer la valeur de la propriété ou de la variable membre.&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3773144983876508185-2503282970598397408?l=populnet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://populnet.blogspot.com/feeds/2503282970598397408/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3773144983876508185&amp;postID=2503282970598397408' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3773144983876508185/posts/default/2503282970598397408'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3773144983876508185/posts/default/2503282970598397408'/><link rel='alternate' type='text/html' href='http://populnet.blogspot.com/2009/01/rcuprer-la-valeur-d-proprit-d-objet.html' title='Récupérer la valeur d&amp;#39;une propriété d&amp;#39;un objet à partir de son nom'/><author><name>Popul</name><uri>http://www.blogger.com/profile/13339110117970769017</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://2.bp.blogspot.com/__831xq1hNEM/SXSGahZtTOI/AAAAAAAAAC0/YTZpJgy1wUI/S220/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3773144983876508185.post-243657417016106173</id><published>2008-12-30T15:37:00.003+01:00</published><updated>2008-12-30T15:38:27.724+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Sharepoint'/><category scheme='http://www.blogger.com/atom/ns#' term='ASP.Net'/><title type='text'>Redirection dans un bloc Try Catch</title><content type='html'>&lt;span xmlns=''&gt;&lt;p&gt;En voulant faire une simple redirection avec &lt;em&gt;Response.Redirect("url")&lt;/em&gt; dans une page ASP.Net, je me suis heurté à un problème. Cette fonction appelle en interne la méthode Response.End() qui a pour rôle de terminer le thread en cours. Le problème c'est que cette méthode génère une exception de type &lt;em&gt;System.Threading.ThreadAbortException&lt;/em&gt;.&lt;br /&gt;&lt;/p&gt;&lt;p&gt; &lt;br /&gt; &lt;/p&gt;&lt;p&gt;Pas forcément de problème si je n'avais pas mis un block &lt;em&gt;try {} catch(Exception exp) {}&lt;/em&gt; autour de la redirection … Du coup, une fois l'instruction de la redirection passée, je tombais à chaque fois dans le block &lt;em&gt;catch {}&lt;/em&gt;. Il est à noter que le comportement est le même avec la méthode &lt;em&gt;Microsoft.SharePoint.Utilities.SPUtility.Redirect("url",flags,Context)&lt;/em&gt; effectuant une redirection dans Sharepoint.&lt;br /&gt;&lt;/p&gt;&lt;p&gt; &lt;br /&gt; &lt;/p&gt;&lt;p&gt;Une bonne solution est d'utiliser une surcharge de la méthode &lt;em&gt;Response.Redirect&lt;/em&gt; prenant en plus un booléen à mettre à &lt;em&gt;false&lt;/em&gt;. Ce dernier évitera l'appel à la méthode &lt;em&gt;Response.End()&lt;/em&gt;. Vous pouvez aussi enlever le bloc &lt;em&gt;try {} catch{}&lt;/em&gt; mais cela n'est pas très propre.&lt;br /&gt;&lt;/p&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3773144983876508185-243657417016106173?l=populnet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://populnet.blogspot.com/feeds/243657417016106173/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3773144983876508185&amp;postID=243657417016106173' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3773144983876508185/posts/default/243657417016106173'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3773144983876508185/posts/default/243657417016106173'/><link rel='alternate' type='text/html' href='http://populnet.blogspot.com/2008/12/redirection-dans-un-bloc-try-catch.html' title='Redirection dans un bloc Try Catch'/><author><name>Popul</name><uri>http://www.blogger.com/profile/13339110117970769017</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://2.bp.blogspot.com/__831xq1hNEM/SXSGahZtTOI/AAAAAAAAAC0/YTZpJgy1wUI/S220/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3773144983876508185.post-4490859856993604245</id><published>2008-12-30T11:14:00.002+01:00</published><updated>2008-12-30T11:16:05.642+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><title type='text'>Charger une dll dynamiquement</title><content type='html'>Grâce à la réflexion, il est tout à fait possible de charger une dll dynamiquement. La classe System.Reflection.Assembly contient une méthode statique LoadFrom prenant comme argument dans une méthode surchargée, une chaine de caractère. En passant à la fonction le nom de la dll, on récupère une référence de l'assembly contenu dans la dll.&lt;br /&gt;&lt;pre class="csharpcode"&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;string&lt;/span&gt; dllName = ConfigurationSettings.AppSettings[&lt;span class="str"&gt;"dll"&lt;/span&gt;];&lt;br /&gt;Assembly assembly = Assembly.LoadFrom(dllName);&lt;/pre&gt;&lt;br /&gt;A partir de cette référence, il est possible d'instancier un type contenu dans l'assembly. Seulement pour manipuler facilement ce type (sans réflexion), il faut connaitre sa classe, ou du moins une interface ou une classe abstraite dont il hérite. Imaginons que ce type hérite d'une interface appelée IInterface contenant une méthode executer() qu'il implémente, voici un bout de code permettant d'invoquer cette fonction :&lt;br /&gt;&lt;pre class="csharpcode"&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;string&lt;/span&gt; typeName = ConfigurationSettings.AppSettings[&lt;span class="str"&gt;"type"&lt;/span&gt;];&lt;br /&gt;Type dllType = assembly.GetType(typeName);&lt;br /&gt;IInterface obj = Activator.CreateInstance(dllType) &lt;span class="kwrd"&gt;as&lt;/span&gt; IInterface;&lt;br /&gt;obj.executer();&lt;/pre&gt;&lt;br /&gt;Dans les 2 exemples ci-dessus, je récupère le nom de la dll et du type dans le fichier de configuration de l'application (de type Console pour l'exemple). Ceci est une bonne façon de faire, si vous souhaitez spécifier une autre dll et un autre type sans recompilation. Voici le fichier de configuration de l'exemple :&lt;br /&gt;&lt;pre class="csharpcode"&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;&amp;lt;?&lt;/span&gt;&lt;span class="html"&gt;xml&lt;/span&gt; &lt;span class="attr"&gt;version&lt;/span&gt;&lt;span class="kwrd"&gt;="1.0"&lt;/span&gt; &lt;span class="attr"&gt;encoding&lt;/span&gt;&lt;span class="kwrd"&gt;="utf-8"&lt;/span&gt; ?&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;configuration&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;  &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;appSettings&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;add&lt;/span&gt; &lt;span class="attr"&gt;key&lt;/span&gt;&lt;span class="kwrd"&gt;="dll"&lt;/span&gt; &lt;span class="attr"&gt;value&lt;/span&gt;&lt;span class="kwrd"&gt;="library.dll"&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;add&lt;/span&gt; &lt;span class="attr"&gt;key&lt;/span&gt;&lt;span class="kwrd"&gt;="type"&lt;/span&gt; &lt;span class="attr"&gt;value&lt;/span&gt;&lt;span class="kwrd"&gt;="library.Class1"&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;  &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;appSettings&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;configuration&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;Pour plus d'infos, veuillez vous référer à l'archive ci-présente :&lt;br /&gt;&lt;iframe scrolling="no" marginheight="0" marginwidth="0" frameborder="0" style="width:240px;height:66px;margin:3px;padding:0;border:1px solid #dde5e9;background-color:#ffffff;" src="http://cid-0d8992a88690ff41.skydrive.live.com/embedrowdetail.aspx/Public/blog/loaderDll.rar"&gt;&lt;/iframe&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3773144983876508185-4490859856993604245?l=populnet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://populnet.blogspot.com/feeds/4490859856993604245/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3773144983876508185&amp;postID=4490859856993604245' title='4 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3773144983876508185/posts/default/4490859856993604245'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3773144983876508185/posts/default/4490859856993604245'/><link rel='alternate' type='text/html' href='http://populnet.blogspot.com/2008/12/charger-une-dll-dynamiquement.html' title='Charger une dll dynamiquement'/><author><name>Popul</name><uri>http://www.blogger.com/profile/13339110117970769017</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://2.bp.blogspot.com/__831xq1hNEM/SXSGahZtTOI/AAAAAAAAAC0/YTZpJgy1wUI/S220/photo.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3773144983876508185.post-7842308685909601187</id><published>2008-12-29T15:53:00.005+01:00</published><updated>2008-12-30T16:34:55.325+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Sharepoint'/><title type='text'>Sharepoint : Provisioning de pages dans un site de publication</title><content type='html'>&lt;span xmlns=""&gt; &lt;p&gt;Dernièrement, j'ai du créer une mise en page (page layout) pour un site de publication. Toutes les pages utilisant cette mise en page contiennent les 2 mêmes webparts ainsi qu'un champ de type HTML remplie toujours de la même manière. &lt;/p&gt;&lt;p&gt;J'ai donc cherché à provisionner la mise en page, pour qu'à la création d'une page, les 2 webparts et le contenu HTML soient ajoutés automatiquement. Sharepoint propose une solution simple de fichier XML et de CAML, dont voici un exemple : &lt;/p&gt;&lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Elements&lt;/span&gt; &lt;span class="attr"&gt;xmlns&lt;/span&gt;&lt;span class="kwrd"&gt;="http://schemas.microsoft.com/sharepoint/"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;File&lt;/span&gt; &lt;span class="attr"&gt;Url&lt;/span&gt;&lt;span class="kwrd"&gt;="PressWIBLayout.aspx"&lt;/span&gt; &lt;span class="attr"&gt;Type&lt;/span&gt;&lt;span class="kwrd"&gt;="GhostableInLibrary"&lt;/span&gt; &lt;span class="attr"&gt;IgnoreIfAlreadyExists&lt;/span&gt;&lt;span class="kwrd"&gt;="TRUE"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;      &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Property&lt;/span&gt; &lt;span class="attr"&gt;Name&lt;/span&gt;&lt;span class="kwrd"&gt;="Title"&lt;/span&gt; &lt;span class="attr"&gt;Value&lt;/span&gt;&lt;span class="kwrd"&gt;="Press WIB Layout"&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;      &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Property&lt;/span&gt; &lt;span class="attr"&gt;Name&lt;/span&gt;&lt;span class="kwrd"&gt;="MasterPageDescription"&lt;/span&gt; &lt;span class="attr"&gt;Value&lt;/span&gt;&lt;span class="kwrd"&gt;="PressWIBLayout"&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;      &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Property&lt;/span&gt; &lt;span class="attr"&gt;Name&lt;/span&gt;&lt;span class="kwrd"&gt;="ContentType"&lt;/span&gt; &lt;span class="attr"&gt;Value&lt;/span&gt;&lt;span class="kwrd"&gt;="$Resources:cmscore,contenttype_pagelayout_name;"&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt;      &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Property&lt;/span&gt; &lt;span class="attr"&gt;Name&lt;/span&gt;&lt;span class="kwrd"&gt;="PublishingPreviewImage"&lt;/span&gt; &lt;span class="attr"&gt;Value&lt;/span&gt;&lt;span class="kwrd"&gt;="~SiteCollection/_catalogs/masterpage/Preview Images/SAMPLELayout.png, ~SiteCollection/_catalogs/masterpage/Preview Images/SAMPLELayout.png"&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   7:  &lt;/span&gt;      &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Property&lt;/span&gt; &lt;span class="attr"&gt;Name&lt;/span&gt;&lt;span class="kwrd"&gt;="PublishingAssociatedContentType"&lt;/span&gt; &lt;span class="attr"&gt;Value&lt;/span&gt;&lt;span class="kwrd"&gt;=";#$Resources:xxx,ContentType_Page_Title;;#0x010100C568DB52D9D0A14D9B2FDCC96666E9F2007948130EC3DB064584E219954237AF390064DEA0F50FC8C147B0B6EA0636C4A7D400ABEA1C761C4D4268997A1EBE2A5C8EA6;#"&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   8:  &lt;/span&gt;      &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Property&lt;/span&gt; &lt;span class="attr"&gt;Name&lt;/span&gt;&lt;span class="kwrd"&gt;="Footer"&lt;/span&gt; &lt;span class="attr"&gt;Value&lt;/span&gt;&lt;span class="kwrd"&gt;="&amp;amp;lt;div class=&amp;amp;quot;pageFooter topic&amp;amp;quot;&amp;amp;gt;&amp;amp;lt;p&amp;amp;gt;$Resources:xxx,SiteTemplate_SPS_FooterTopic;&amp;amp;lt;/p&amp;amp;gt;&amp;amp;lt;/div&amp;amp;gt;"&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   9:  &lt;/span&gt;      &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;AllUsersWebPart&lt;/span&gt; &lt;span class="attr"&gt;WebPartZoneID&lt;/span&gt;&lt;span class="kwrd"&gt;="ZoneMainRightCol"&lt;/span&gt; &lt;span class="attr"&gt;WebPartOrder&lt;/span&gt;&lt;span class="kwrd"&gt;="1"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  10:  &lt;/span&gt;        &lt;span class="kwrd"&gt;&amp;lt;!&lt;/span&gt;[CDATA[&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  11:  &lt;/span&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;webParts&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  12:  &lt;/span&gt;  &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;webPart&lt;/span&gt; &lt;span class="attr"&gt;xmlns&lt;/span&gt;&lt;span class="kwrd"&gt;="http://schemas.microsoft.com/WebPart/v3"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  13:  &lt;/span&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;metaData&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  14:  &lt;/span&gt;      &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;type&lt;/span&gt; &lt;span class="attr"&gt;name&lt;/span&gt;&lt;span class="kwrd"&gt;="XX.XXX.Runtime.Webparts.FeedBack, XX.XXX.Runtime, Version=1.0.0.0, Culture=neutral, PublicKeyToken=xxxxxxxxxx"&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  15:  &lt;/span&gt;      &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;importErrorMessage&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;Impossible d'importer ce WebPart.&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;importErrorMessage&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  16:  &lt;/span&gt;    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;metaData&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  17:  &lt;/span&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;data&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  18:  &lt;/span&gt;      &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;properties&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  19:  &lt;/span&gt;        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;property&lt;/span&gt; &lt;span class="attr"&gt;name&lt;/span&gt;&lt;span class="kwrd"&gt;="AllowClose"&lt;/span&gt; &lt;span class="attr"&gt;type&lt;/span&gt;&lt;span class="kwrd"&gt;="bool"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;True&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;property&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  20:  &lt;/span&gt;        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;property&lt;/span&gt; &lt;span class="attr"&gt;name&lt;/span&gt;&lt;span class="kwrd"&gt;="Width"&lt;/span&gt; &lt;span class="attr"&gt;type&lt;/span&gt;&lt;span class="kwrd"&gt;="string"&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  21:  &lt;/span&gt;        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;property&lt;/span&gt; &lt;span class="attr"&gt;name&lt;/span&gt;&lt;span class="kwrd"&gt;="AllowMinimize"&lt;/span&gt; &lt;span class="attr"&gt;type&lt;/span&gt;&lt;span class="kwrd"&gt;="bool"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;True&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;property&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  22:  &lt;/span&gt;        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;property&lt;/span&gt; &lt;span class="attr"&gt;name&lt;/span&gt;&lt;span class="kwrd"&gt;="AllowConnect"&lt;/span&gt; &lt;span class="attr"&gt;type&lt;/span&gt;&lt;span class="kwrd"&gt;="bool"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;True&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;property&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  23:  &lt;/span&gt;        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;property&lt;/span&gt; &lt;span class="attr"&gt;name&lt;/span&gt;&lt;span class="kwrd"&gt;="ChromeType"&lt;/span&gt; &lt;span class="attr"&gt;type&lt;/span&gt;&lt;span class="kwrd"&gt;="chrometype"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;Default&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;property&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  24:  &lt;/span&gt;        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;property&lt;/span&gt; &lt;span class="attr"&gt;name&lt;/span&gt;&lt;span class="kwrd"&gt;="TitleIconImageUrl"&lt;/span&gt; &lt;span class="attr"&gt;type&lt;/span&gt;&lt;span class="kwrd"&gt;="string"&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  25:  &lt;/span&gt;        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;property&lt;/span&gt; &lt;span class="attr"&gt;name&lt;/span&gt;&lt;span class="kwrd"&gt;="Description"&lt;/span&gt; &lt;span class="attr"&gt;type&lt;/span&gt;&lt;span class="kwrd"&gt;="string"&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  26:  &lt;/span&gt;        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;property&lt;/span&gt; &lt;span class="attr"&gt;name&lt;/span&gt;&lt;span class="kwrd"&gt;="Hidden"&lt;/span&gt; &lt;span class="attr"&gt;type&lt;/span&gt;&lt;span class="kwrd"&gt;="bool"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;False&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;property&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  27:  &lt;/span&gt;        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;property&lt;/span&gt; &lt;span class="attr"&gt;name&lt;/span&gt;&lt;span class="kwrd"&gt;="TitleUrl"&lt;/span&gt; &lt;span class="attr"&gt;type&lt;/span&gt;&lt;span class="kwrd"&gt;="string"&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  28:  &lt;/span&gt;        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;property&lt;/span&gt; &lt;span class="attr"&gt;name&lt;/span&gt;&lt;span class="kwrd"&gt;="AllowEdit"&lt;/span&gt; &lt;span class="attr"&gt;type&lt;/span&gt;&lt;span class="kwrd"&gt;="bool"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;True&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;property&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  29:  &lt;/span&gt;        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;property&lt;/span&gt; &lt;span class="attr"&gt;name&lt;/span&gt;&lt;span class="kwrd"&gt;="Height"&lt;/span&gt; &lt;span class="attr"&gt;type&lt;/span&gt;&lt;span class="kwrd"&gt;="string"&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  30:  &lt;/span&gt;        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;property&lt;/span&gt; &lt;span class="attr"&gt;name&lt;/span&gt;&lt;span class="kwrd"&gt;="MissingAssembly"&lt;/span&gt; &lt;span class="attr"&gt;type&lt;/span&gt;&lt;span class="kwrd"&gt;="string"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;Impossible d'importer ce composant WebPart.&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;property&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  31:  &lt;/span&gt;        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;property&lt;/span&gt; &lt;span class="attr"&gt;name&lt;/span&gt;&lt;span class="kwrd"&gt;="HelpUrl"&lt;/span&gt; &lt;span class="attr"&gt;type&lt;/span&gt;&lt;span class="kwrd"&gt;="string"&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  32:  &lt;/span&gt;        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;property&lt;/span&gt; &lt;span class="attr"&gt;name&lt;/span&gt;&lt;span class="kwrd"&gt;="Title"&lt;/span&gt; &lt;span class="attr"&gt;type&lt;/span&gt;&lt;span class="kwrd"&gt;="string"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;XXX:: Feed Back&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;property&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  33:  &lt;/span&gt;        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;property&lt;/span&gt; &lt;span class="attr"&gt;name&lt;/span&gt;&lt;span class="kwrd"&gt;="CatalogIconImageUrl"&lt;/span&gt; &lt;span class="attr"&gt;type&lt;/span&gt;&lt;span class="kwrd"&gt;="string"&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  34:  &lt;/span&gt;        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;property&lt;/span&gt; &lt;span class="attr"&gt;name&lt;/span&gt;&lt;span class="kwrd"&gt;="Direction"&lt;/span&gt; &lt;span class="attr"&gt;type&lt;/span&gt;&lt;span class="kwrd"&gt;="direction"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;NotSet&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;property&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  35:  &lt;/span&gt;        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;property&lt;/span&gt; &lt;span class="attr"&gt;name&lt;/span&gt;&lt;span class="kwrd"&gt;="ChromeState"&lt;/span&gt; &lt;span class="attr"&gt;type&lt;/span&gt;&lt;span class="kwrd"&gt;="chromestate"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;Normal&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;property&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  36:  &lt;/span&gt;        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;property&lt;/span&gt; &lt;span class="attr"&gt;name&lt;/span&gt;&lt;span class="kwrd"&gt;="AllowZoneChange"&lt;/span&gt; &lt;span class="attr"&gt;type&lt;/span&gt;&lt;span class="kwrd"&gt;="bool"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;True&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;property&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  37:  &lt;/span&gt;        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;property&lt;/span&gt; &lt;span class="attr"&gt;name&lt;/span&gt;&lt;span class="kwrd"&gt;="AllowHide"&lt;/span&gt; &lt;span class="attr"&gt;type&lt;/span&gt;&lt;span class="kwrd"&gt;="bool"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;True&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;property&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  38:  &lt;/span&gt;        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;property&lt;/span&gt; &lt;span class="attr"&gt;name&lt;/span&gt;&lt;span class="kwrd"&gt;="HelpMode"&lt;/span&gt; &lt;span class="attr"&gt;type&lt;/span&gt;&lt;span class="kwrd"&gt;="helpmode"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;Modeless&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;property&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  39:  &lt;/span&gt;        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;property&lt;/span&gt; &lt;span class="attr"&gt;name&lt;/span&gt;&lt;span class="kwrd"&gt;="ExportMode"&lt;/span&gt; &lt;span class="attr"&gt;type&lt;/span&gt;&lt;span class="kwrd"&gt;="exportmode"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;All&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;property&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  40:  &lt;/span&gt;      &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;properties&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  41:  &lt;/span&gt;    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;data&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  42:  &lt;/span&gt;  &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;webPart&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  43:  &lt;/span&gt;&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;webParts&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;          &lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  44:  &lt;/span&gt;          ]]&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  45:  &lt;/span&gt;      &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;AllUsersWebPart&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  46:  &lt;/span&gt;      &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;AllUsersWebPart&lt;/span&gt; &lt;span class="attr"&gt;WebPartZoneID&lt;/span&gt;&lt;span class="kwrd"&gt;="ZoneRightTopCol"&lt;/span&gt; &lt;span class="attr"&gt;WebPartOrder&lt;/span&gt;&lt;span class="kwrd"&gt;="1"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  47:  &lt;/span&gt;        &lt;span class="kwrd"&gt;&amp;lt;!&lt;/span&gt;[CDATA[        &lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  48:  &lt;/span&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;webParts&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  49:  &lt;/span&gt;  &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;webPart&lt;/span&gt; &lt;span class="attr"&gt;xmlns&lt;/span&gt;&lt;span class="kwrd"&gt;="http://schemas.microsoft.com/WebPart/v3"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  50:  &lt;/span&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;metaData&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  51:  &lt;/span&gt;      &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;type&lt;/span&gt; &lt;span class="attr"&gt;name&lt;/span&gt;&lt;span class="kwrd"&gt;="XX.XXX.Runtime.Webparts.LatestWIBs, XX.XXX.Runtime, Version=1.0.0.0, Culture=neutral, PublicKeyToken=xxxxxxxxxxx"&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  52:  &lt;/span&gt;      &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;importErrorMessage&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;Cannot import this Web Part.&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;importErrorMessage&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  53:  &lt;/span&gt;    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;metaData&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  54:  &lt;/span&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;data&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  55:  &lt;/span&gt;      &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;properties&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  56:  &lt;/span&gt;        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;property&lt;/span&gt; &lt;span class="attr"&gt;name&lt;/span&gt;&lt;span class="kwrd"&gt;="Title"&lt;/span&gt; &lt;span class="attr"&gt;type&lt;/span&gt;&lt;span class="kwrd"&gt;="string"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;XXX:: latest weeks in brief&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;property&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  57:  &lt;/span&gt;        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;property&lt;/span&gt; &lt;span class="attr"&gt;name&lt;/span&gt;&lt;span class="kwrd"&gt;="WIBTitle"&lt;/span&gt; &lt;span class="attr"&gt;type&lt;/span&gt;&lt;span class="kwrd"&gt;="bool"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;False&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;property&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  58:  &lt;/span&gt;        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;property&lt;/span&gt; &lt;span class="attr"&gt;name&lt;/span&gt;&lt;span class="kwrd"&gt;="NumberOfElements"&lt;/span&gt; &lt;span class="attr"&gt;type&lt;/span&gt;&lt;span class="kwrd"&gt;="int"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;1&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;property&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  59:  &lt;/span&gt;      &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;properties&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  60:  &lt;/span&gt;    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;data&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  61:  &lt;/span&gt;  &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;webPart&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  62:  &lt;/span&gt;&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;webParts&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  63:  &lt;/span&gt;          ]]&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  64:  &lt;/span&gt;      &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;AllUsersWebPart&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  65:  &lt;/span&gt;    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;File&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  66:  &lt;/span&gt;  &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Module&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  67:  &lt;/span&gt;&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Elements&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;L'attribut Url de l'élément File spécifie la mise en page concernée et l'attribut IgnoreIfAlreadyExists=TRUE dit à Sharepoint que si la mise en page existe déjà, ce n'est pas la peine de la rajouter. &lt;/p&gt;&lt;p&gt;Après compilation, déploiement et activation, le résultat est impeccable : une page créée avec la mise en page ci-dessus contient bien mes 2 webparts. Cependant, je souhaitais modifier quelques propriétés dans une des 2 webparts. Je recompile, redéploie et réactive ma feature. Lorsque je recréée une page, je m'aperçois que ma page contient, non pas 2 webparts, mais 4, 2 de chaque en fait. &lt;/p&gt;&lt;p&gt;En faisant quelques tests, je me rends compte qu'a chaque fois que je désactive/réactive la feature, une instance pour chaque webpart spécifiée dans le module XML est ajoutée à chaque page créée avec cette mise en page. Pourtant, j'ai bien spécifié d'ignorer la mise en page si elle existe déjà dans le catalogue de la collection de site, via l'attribut IgnoreIfAlreadyExists défini à true.&lt;/p&gt;&lt;p&gt;En fait, la mise est bien ignorée si elle existe déjà. Malheureusement, ce n'est pas le cas des webparts spécifiées à l'intérieur. Pour moi, ceci est un bug de Sharepoint, peut-être est-il déjà référencé par Microsoft … Une autre solution de provisioning serait d'utiliser un EventReceiver ajoutant les webparts voulues à la création d'une page. &lt;/p&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3773144983876508185-7842308685909601187?l=populnet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://populnet.blogspot.com/feeds/7842308685909601187/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3773144983876508185&amp;postID=7842308685909601187' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3773144983876508185/posts/default/7842308685909601187'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3773144983876508185/posts/default/7842308685909601187'/><link rel='alternate' type='text/html' href='http://populnet.blogspot.com/2008/12/sharepoint-provisioning-de-pages-dans.html' title='Sharepoint : Provisioning de pages dans un site de publication'/><author><name>Popul</name><uri>http://www.blogger.com/profile/13339110117970769017</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://2.bp.blogspot.com/__831xq1hNEM/SXSGahZtTOI/AAAAAAAAAC0/YTZpJgy1wUI/S220/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3773144983876508185.post-8026226727106454574</id><published>2008-12-18T16:31:00.000+01:00</published><updated>2008-12-29T16:32:28.570+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Developpez.com'/><title type='text'>Article sur Entity Framework</title><content type='html'>&lt;span xmlns=''&gt;&lt;p&gt;Developpez.com vient de publier un article  que j'ai écrit sur Entity Framework, la solution mapping objet-relationnel de Microsoft : &lt;a href='http://pmusso.developpez.com/tutoriels/dotnet/entity-framework/introduction/'&gt;http://pmusso.developpez.com/tutoriels/dotnet/entity-framework/introduction/&lt;/a&gt;.&lt;br /&gt;&lt;/p&gt;&lt;p&gt; &lt;br /&gt; &lt;/p&gt;&lt;p&gt;Dans l'article, vous trouverez une partie théorique sur le framework expliquant entre autre le concept d'entités, ce qu'est le modèle conceptuel et ses 3 schémas XML.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Dans une 2ème partie, vous apprendrez à vous servir de l'assistant de Visual Studio pour générer vos objets métiers à partir d'une base de données déjà  établie.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;En dernier lieu, l'utilisation des entités et du contexte sont expliqués en détail. Vous trouverez aussi quelques informations sur l'accès concurrentiel et les transactions.&lt;br /&gt;&lt;/p&gt;&lt;p&gt; &lt;br /&gt; &lt;/p&gt;&lt;p&gt;Bonne lecture ! :)&lt;br /&gt;&lt;/p&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3773144983876508185-8026226727106454574?l=populnet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://populnet.blogspot.com/feeds/8026226727106454574/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3773144983876508185&amp;postID=8026226727106454574' title='1 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3773144983876508185/posts/default/8026226727106454574'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3773144983876508185/posts/default/8026226727106454574'/><link rel='alternate' type='text/html' href='http://populnet.blogspot.com/2008/12/article-sur-entity-framework.html' title='Article sur Entity Framework'/><author><name>Popul</name><uri>http://www.blogger.com/profile/13339110117970769017</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://2.bp.blogspot.com/__831xq1hNEM/SXSGahZtTOI/AAAAAAAAAC0/YTZpJgy1wUI/S220/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3773144983876508185.post-3548763989981189239</id><published>2008-12-10T21:39:00.004+01:00</published><updated>2008-12-10T22:29:43.539+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Entity Framework'/><title type='text'>POCO avec Entity Framework (1/2)</title><content type='html'>Qu'est-ce que POCO déjà ?&lt;br /&gt;&lt;br /&gt;Cela signifie Plain Old Code Object. Le "C" peut vouloir dire aussi CSharp ou CLR Object. Dans le monde Java on retrouve ainsi l'acronyme POJO qui veut dire Plain Old Java Object, mais le sens est le même.&lt;br /&gt;&lt;br /&gt;POCO signifie de laisser tel quel ses classes métiers lorsqu'on souhaite les rendre persistantes avec un outil de mapping objet-relationnel. C'est à dire que les classes métiers ne sont pas modifiées pour les faire fonctionner avec l'outil.&lt;br /&gt;&lt;br /&gt;Entity Framework fonctionne avec des entités. Ce sont des classes dérivant de la classe &lt;em&gt;System.Data.Objects.DataClasses.EntityObject.&lt;/em&gt; Une autre solution est d'implémenter 3 interfaces fournies par le framework .Le problème avec ce design, c'est que les classes métiers doivent être modifiées pour fonctionner avec Entity Framework. Du coup, on en déduie qu'Entity Framework ne supporte pas le concept POCO, en tout cas pas dans sa version 1.&lt;br /&gt;&lt;br /&gt;L'équipe d'Entity Framework travaille sur une solution afin d'annuler la dépendance qu'il existe entre les classes métiers et le framework. Vous trouverez une partie de leur reflexion sur un de leur &lt;a href="http://blogs.msdn.com/efdesign/archive/2008/08/01/discussion-about-api-changes-necessary-for-poco.aspx"&gt;blog&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Une autre solution appellée &lt;a href="http://www.codeplex.com/efcontrib/Wiki/View.aspx?title=PostSharp4EF&amp;amp;referringTitle=Home"&gt;PostSharp4EF &lt;/a&gt;a été proposée par &lt;a href="http://www.sitechno.com/Blog/default.aspx"&gt;Ruurd Boeke&lt;/a&gt;. Celle-ci est plutôt élégante car elle utilise la programmation orientée aspect (avec Postsharp) pour implémenter lors d'une 2ème compilation les interfaces requises pour rendre persistentes nos classes POCO.&lt;br /&gt;&lt;br /&gt;PostSharp4EF exécute entre autres les tâches suivantes :&lt;br /&gt;&lt;ul&gt;&lt;li&gt;implémente les interfaces IPOCO : IEntityWithChangeTracker, IEntityWithKey et IEntityWithRelaships&lt;/li&gt;&lt;li&gt;Ajoute l'attribut EdmEntityType sur la classe, l'attribut EdmScallarProperty sur chaque propriété, l'attribut EdmRelashionShip et EdmSchema sur l'assembly&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Toutes ces tâches sont exécutées grâce à PostSharp et à l'attribut &lt;em&gt;[assembly: Poco("InheritanceTypeConnection")]&lt;/em&gt;, celui-ci étant implémenté par PostSharp4EF.&lt;/p&gt;&lt;p&gt;Nous verrons dans un prochain billet un petit exemple d'implémentation.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3773144983876508185-3548763989981189239?l=populnet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://populnet.blogspot.com/feeds/3548763989981189239/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3773144983876508185&amp;postID=3548763989981189239' title='3 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3773144983876508185/posts/default/3548763989981189239'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3773144983876508185/posts/default/3548763989981189239'/><link rel='alternate' type='text/html' href='http://populnet.blogspot.com/2008/12/poco-avec-entity-framework.html' title='POCO avec Entity Framework (1/2)'/><author><name>Popul</name><uri>http://www.blogger.com/profile/13339110117970769017</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://2.bp.blogspot.com/__831xq1hNEM/SXSGahZtTOI/AAAAAAAAAC0/YTZpJgy1wUI/S220/photo.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3773144983876508185.post-2792025825546219621</id><published>2008-12-03T13:59:00.007+01:00</published><updated>2008-12-30T16:37:55.344+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><title type='text'>Exécuter une chaine de caractère avec CodeDom et la réflexion</title><content type='html'>&lt;span xmlns=""&gt; &lt;p&gt;Grâce à l'API CodeDom, il est assez facile de générer des assemblies dynamiquement. Le framework .Net permet d'exécuter un assembly grâce à la réflexion. A partir de ces 2 constats, il devient possible d'exécuter une chaine de caractère contenant du code, un peu comme on le ferait dans un langage de script. &lt;/p&gt;&lt;p&gt;Dans un langage statique comme le C#, le code doit d'abord être compilé, ce que CodeDom fait très bien. Il ne reste plus qu'à utiliser la réflexion pour exécuter le code compilé. Voici l'exemple d'une fonction montrant cela : &lt;/p&gt;&lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System;&lt;/pre&gt;&lt;/div&gt;&lt;div class="csharpcode"&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.CodeDom;&lt;/pre&gt;&lt;/div&gt;&lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.CodeDom.Compiler;&lt;/pre&gt;&lt;/div&gt;&lt;div class="csharpcode"&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Reflection;&lt;/pre&gt;&lt;/div&gt;&lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt; &lt;/pre&gt;&lt;/div&gt;&lt;div class="csharpcode"&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt;&lt;span class="kwrd"&gt;namespace&lt;/span&gt; GenererMethode&lt;/pre&gt;&lt;/div&gt;&lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   7:  &lt;/span&gt;{&lt;/pre&gt;&lt;/div&gt;&lt;div class="csharpcode"&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   8:  &lt;/span&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; Generateur&lt;/pre&gt;&lt;/div&gt;&lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   9:  &lt;/span&gt;    {&lt;/pre&gt;&lt;/div&gt;&lt;div class="csharpcode"&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  10:  &lt;/span&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Executer(&lt;span class="kwrd"&gt;string&lt;/span&gt;[] references, &lt;span class="kwrd"&gt;string&lt;/span&gt;[] usings, &lt;span class="kwrd"&gt;string&lt;/span&gt; strCode)&lt;/pre&gt;&lt;/div&gt;&lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  11:  &lt;/span&gt;        {&lt;/pre&gt;&lt;/div&gt;&lt;div class="csharpcode"&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  12:  &lt;/span&gt;            CompilerParameters compilerParameters = &lt;span class="kwrd"&gt;new&lt;/span&gt; CompilerParameters();&lt;/pre&gt;&lt;/div&gt;&lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  13:  &lt;/span&gt;            compilerParameters.GenerateExecutable = &lt;span class="kwrd"&gt;false&lt;/span&gt;;&lt;/pre&gt;&lt;/div&gt;&lt;div class="csharpcode"&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  14:  &lt;/span&gt;            compilerParameters.GenerateInMemory = &lt;span class="kwrd"&gt;true&lt;/span&gt;;&lt;/pre&gt;&lt;/div&gt;&lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  15:  &lt;/span&gt;            compilerParameters.IncludeDebugInformation = &lt;span class="kwrd"&gt;true&lt;/span&gt;;&lt;/pre&gt;&lt;/div&gt;&lt;div class="csharpcode"&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  16:  &lt;/span&gt; &lt;/pre&gt;&lt;/div&gt;&lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  17:  &lt;/span&gt;            &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (&lt;span class="kwrd"&gt;string&lt;/span&gt; reference &lt;span class="kwrd"&gt;in&lt;/span&gt; references)&lt;/pre&gt;&lt;/div&gt;&lt;div class="csharpcode"&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  18:  &lt;/span&gt;            {&lt;/pre&gt;&lt;/div&gt;&lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  19:  &lt;/span&gt;                compilerParameters.ReferencedAssemblies.Add(reference);&lt;/pre&gt;&lt;/div&gt;&lt;div class="csharpcode"&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  20:  &lt;/span&gt;            }&lt;/pre&gt;&lt;/div&gt;&lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  21:  &lt;/span&gt; &lt;/pre&gt;&lt;/div&gt;&lt;div class="csharpcode"&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  22:  &lt;/span&gt;            CodeCompileUnit code = &lt;span class="kwrd"&gt;new&lt;/span&gt; CodeCompileUnit();&lt;/pre&gt;&lt;/div&gt;&lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  23:  &lt;/span&gt;            code.UserData.Add(&lt;span class="str"&gt;"AllowLateBound"&lt;/span&gt;, &lt;span class="kwrd"&gt;false&lt;/span&gt;);&lt;/pre&gt;&lt;/div&gt;&lt;div class="csharpcode"&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  24:  &lt;/span&gt;            code.UserData.Add(&lt;span class="str"&gt;"RequireVariableDeclaration"&lt;/span&gt;, &lt;span class="kwrd"&gt;true&lt;/span&gt;);&lt;/pre&gt;&lt;/div&gt;&lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  25:  &lt;/span&gt; &lt;/pre&gt;&lt;/div&gt;&lt;div class="csharpcode"&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  26:  &lt;/span&gt;            CodeNamespace nameSpace = &lt;span class="kwrd"&gt;new&lt;/span&gt; CodeNamespace(&lt;span class="str"&gt;"GenererMethode"&lt;/span&gt;);&lt;/pre&gt;&lt;/div&gt;&lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  27:  &lt;/span&gt;            &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (&lt;span class="kwrd"&gt;string&lt;/span&gt; _using &lt;span class="kwrd"&gt;in&lt;/span&gt; usings)&lt;/pre&gt;&lt;/div&gt;&lt;div class="csharpcode"&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  28:  &lt;/span&gt;            {&lt;/pre&gt;&lt;/div&gt;&lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  29:  &lt;/span&gt;                nameSpace.Imports.Add(&lt;span class="kwrd"&gt;new&lt;/span&gt; CodeNamespaceImport(_using));&lt;/pre&gt;&lt;/div&gt;&lt;div class="csharpcode"&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  30:  &lt;/span&gt;            }&lt;/pre&gt;&lt;/div&gt;&lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  31:  &lt;/span&gt;            code.Namespaces.Add(nameSpace);&lt;/pre&gt;&lt;/div&gt;&lt;div class="csharpcode"&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  32:  &lt;/span&gt; &lt;/pre&gt;&lt;/div&gt;&lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  33:  &lt;/span&gt;            CodeTypeDeclaration classObject = &lt;span class="kwrd"&gt;new&lt;/span&gt; CodeTypeDeclaration(&lt;span class="str"&gt;"Test"&lt;/span&gt;);&lt;/pre&gt;&lt;/div&gt;&lt;div class="csharpcode"&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  34:  &lt;/span&gt;            nameSpace.Types.Add(classObject);&lt;/pre&gt;&lt;/div&gt;&lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  35:  &lt;/span&gt;            classObject.TypeAttributes = TypeAttributes.Public;&lt;/pre&gt;&lt;/div&gt;&lt;div class="csharpcode"&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  36:  &lt;/span&gt; &lt;/pre&gt;&lt;/div&gt;&lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  37:  &lt;/span&gt;            CodeMemberMethod method = &lt;span class="kwrd"&gt;new&lt;/span&gt; CodeMemberMethod();&lt;/pre&gt;&lt;/div&gt;&lt;div class="csharpcode"&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  38:  &lt;/span&gt;            method.Attributes = MemberAttributes.Public  MemberAttributes.Static;&lt;/pre&gt;&lt;/div&gt;&lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  39:  &lt;/span&gt;            method.Name = &lt;span class="str"&gt;"HelloWorld"&lt;/span&gt;;&lt;/pre&gt;&lt;/div&gt;&lt;div class="csharpcode"&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  40:  &lt;/span&gt;            CodeSnippetExpression csu = &lt;span class="kwrd"&gt;new&lt;/span&gt; CodeSnippetExpression(strCode);&lt;/pre&gt;&lt;/div&gt;&lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  41:  &lt;/span&gt;            method.Statements.Add(csu);&lt;/pre&gt;&lt;/div&gt;&lt;div class="csharpcode"&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  42:  &lt;/span&gt;            classObject.Members.Add(method);&lt;/pre&gt;&lt;/div&gt;&lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  43:  &lt;/span&gt; &lt;/pre&gt;&lt;/div&gt;&lt;div class="csharpcode"&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  44:  &lt;/span&gt;            CodeGenerator.ValidateIdentifiers(code);&lt;/pre&gt;&lt;/div&gt;&lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  45:  &lt;/span&gt; &lt;/pre&gt;&lt;/div&gt;&lt;div class="csharpcode"&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  46:  &lt;/span&gt;            CodeDomProvider codeProvider = CodeDomProvider.CreateProvider(&lt;span class="str"&gt;"C#"&lt;/span&gt;);&lt;/pre&gt;&lt;/div&gt;&lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  47:  &lt;/span&gt; &lt;/pre&gt;&lt;/div&gt;&lt;div class="csharpcode"&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  48:  &lt;/span&gt;            var result = codeProvider.CompileAssemblyFromDom(compilerParameters, code);&lt;/pre&gt;&lt;/div&gt;&lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  49:  &lt;/span&gt; &lt;/pre&gt;&lt;/div&gt;&lt;div class="csharpcode"&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  50:  &lt;/span&gt;            Assembly assembly = result.CompiledAssembly;&lt;/pre&gt;&lt;/div&gt;&lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  51:  &lt;/span&gt;            Type type = assembly.GetType(&lt;span class="str"&gt;"GenererMethode.Test"&lt;/span&gt;);&lt;/pre&gt;&lt;/div&gt;&lt;div class="csharpcode"&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  52:  &lt;/span&gt;            type.InvokeMember(&lt;span class="str"&gt;"HelloWorld"&lt;/span&gt;, BindingFlags.InvokeMethod, &lt;span class="kwrd"&gt;null&lt;/span&gt;, &lt;span class="kwrd"&gt;null&lt;/span&gt;, &lt;span class="kwrd"&gt;null&lt;/span&gt;);&lt;/pre&gt;&lt;/div&gt;&lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  53:  &lt;/span&gt;        }&lt;/pre&gt;&lt;/div&gt;&lt;div class="csharpcode"&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  54:  &lt;/span&gt;    }&lt;/pre&gt;&lt;/div&gt;&lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  55:  &lt;/span&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;La méthode "Executer" crée une classe quelconque et créé aussi une méthode statique contenant la chaine de caractère passée en paramètre. Pour que le code de la chaine de caractères puisse s'exécuter, la méthode prend en paramètre les dll contenant les assemblies et les usings nécessaires. Finalement, la méthode générée est exécutée via la réflexion.&lt;br /&gt;&lt;/p&gt;&lt;div class="csharpcode"&gt;&lt;br /&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;Generateur.Executer(&lt;span class="kwrd"&gt;new&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt;[] { &lt;span class="str"&gt;"System.dll"&lt;/span&gt; },&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;                                &lt;span class="kwrd"&gt;new&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt;[] { &lt;span class="str"&gt;"System"&lt;/span&gt; },&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;                                &lt;span class="str"&gt;"Console.WriteLine(\"Hello World\")"&lt;/span&gt;);&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;/span&gt;&lt;span xmlns=""&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3773144983876508185-2792025825546219621?l=populnet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://populnet.blogspot.com/feeds/2792025825546219621/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3773144983876508185&amp;postID=2792025825546219621' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3773144983876508185/posts/default/2792025825546219621'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3773144983876508185/posts/default/2792025825546219621'/><link rel='alternate' type='text/html' href='http://populnet.blogspot.com/2008/12/excuter-une-chaine-de-caractre.html' title='Exécuter une chaine de caractère avec CodeDom et la réflexion'/><author><name>Popul</name><uri>http://www.blogger.com/profile/13339110117970769017</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://2.bp.blogspot.com/__831xq1hNEM/SXSGahZtTOI/AAAAAAAAAC0/YTZpJgy1wUI/S220/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3773144983876508185.post-4156490359719621430</id><published>2008-11-27T14:50:00.000+01:00</published><updated>2008-11-30T14:56:08.658+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Entity Framework'/><title type='text'>Peut-on utiliser des classes métiers n'héritant pas de "EntityObject" ?</title><content type='html'>La réponse est oui ! Au minimum, il est nécessaire que vos classes héritent des interfaces suivantes :&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;&lt;u&gt;IEntityWithChangeTracker :&lt;/u&gt; Active le suivi des modifications.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;u&gt;IEntityWithKey.&lt;/u&gt; Facultatif : Expose une clé d'entité.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;u&gt;IEntityWithRelationships :&lt;/u&gt; Obligatoire pour les entités présentant des associations. &lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;Pour plus d'informations, voici la &lt;a href="http://msdn.microsoft.com/fr-fr/library/bb738453.aspx"&gt;documentation officielle&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Implémenter ces 3 interfaces sous entend que vos classes métiers doivent être modifiées pour utiliser la persistance avec Entity Framework. En d'autres termes, le principe de faible couplage / forte cohérence n'est pas respecté puisque les classes métiers contiennent à la fois de la logique métier et de la logique de persistance. De plus, dans certains scénarios, il n'est pas possible de modifier ses classes métiers.&lt;br /&gt;&lt;br /&gt;On peut en tirer la conclusion suivante : Entity Framework ne permet pas d'utiliser des classes POCO (pour Plain Old Code Object). D'autres outils le permettent comme NHibernate avec l'utilisation d'objets proxy. Danny Simmons, développeur de l'équipe d'Entity Framework s'explique à &lt;a href="http://blogs.msdn.com/dsimmons/archive/2007/06/02/persistence-ignorance-ok-i-think-i-get-it-now.aspx"&gt;ce sujet&lt;/a&gt;. Souhaitons que ce manque soit comblé dans les prochaines versions de l'outil.&lt;br /&gt;&lt;br /&gt;Cependant, sachez qu'il est possible de contourner ce manque avec l'utilisation de la programmation orientée aspect. Sans rentrer dans les détails, &lt;a href="http://www.postsharp.org/"&gt;PostSharp&lt;/a&gt; permet d'injecter du code lors d'une 2ème phase de compilation et donc d'implémenter les 3 interfaces nécessaires sur les classes POCO. &lt;a href="http://www.codeplex.com/efcontrib"&gt;Un projet&lt;/a&gt; a d'ailleurs été réalisé à ce sujet. Vous trouverez plus d'information sur &lt;a href="http://www.sitechno.com/Blog/IntroducingEntityFrameworkContribEasyIPocoImplementationV01.aspx"&gt;son blog&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3773144983876508185-4156490359719621430?l=populnet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://populnet.blogspot.com/feeds/4156490359719621430/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3773144983876508185&amp;postID=4156490359719621430' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3773144983876508185/posts/default/4156490359719621430'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3773144983876508185/posts/default/4156490359719621430'/><link rel='alternate' type='text/html' href='http://populnet.blogspot.com/2008/11/peut-on-utiliser-des-classes-mtiers.html' title='Peut-on utiliser des classes métiers n&apos;héritant pas de &quot;EntityObject&quot; ?'/><author><name>Popul</name><uri>http://www.blogger.com/profile/13339110117970769017</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://2.bp.blogspot.com/__831xq1hNEM/SXSGahZtTOI/AAAAAAAAAC0/YTZpJgy1wUI/S220/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3773144983876508185.post-3284186974878284205</id><published>2008-11-25T13:44:00.001+01:00</published><updated>2008-11-30T14:05:12.770+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Entity Framework'/><title type='text'>Lecture des données</title><content type='html'>Entity Framework offre 3 types de possibilité pour requêter la source de données :&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;LinQ To Entities&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Entity SQL&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Les méthodes génératrices de requête de "ObjectQuery&amp;lt;T&amp;gt;"&lt;/li&gt;&lt;/ul&gt;LinQ To Entities permet d'écrire des requêtes syntaxiquement proche du SQL, et cela directement en C# ou VB.Net. L'avantage majeur vient du fait que les requêtes produites sont vérifiées à la compilation et non plus à l'exécution. Comme pour chaque implémentation de LinQ, chaque requête est transformée en un arbre d'expression (créé par l'objet ObjectContext) qui est traduit en SQL par le fournisseur de données final. Le résultat d'une requête LinQ to Entities est de type "IQueryable&amp;lt;T&amp;gt;" où T est le type spécifié dans la clause SELECT de la requête.&lt;br /&gt;Voici donc un exemple de requête LinQ to Entities :&lt;br /&gt;&lt;pre&gt;&lt;div name="code"&gt;&lt;br /&gt;var requete = from publication in bdd.Publication&lt;br /&gt;                         select publication;&lt;br /&gt;&lt;/div&gt;&lt;/pre&gt;&lt;br /&gt;Le résultat est de type "IQueryable&amp;lt;Publication&amp;gt;". Il est possible d'itérer sur les résultats avec une simple boucle "foreach". Vu que "IQueryable&amp;lt;T&amp;gt;" implémente un énumérateur, sachez que la requête vers la source de données est uniquement exécutée lors du parcours des résultats. Pour plus d'information, veuillez vous référencer à la documentation officielle de l'objet &lt;a href="http://msdn.microsoft.com/fr-fr/library/bb337580.aspx"&gt;"IQueryable&amp;lt;Publication&amp;gt;"&lt;/a&gt;.&lt;br /&gt;Linq to Entities supporte un ensemble de méthodes pour requêter la source de données dont voici une liste non exhaustive (&lt;a href="http://msdn.microsoft.com/fr-fr/library/bb738550.aspx"&gt;url&lt;/a&gt; de la liste complète) :&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;Select, SelectMany&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Where&lt;/li&gt;&lt;br /&gt;&lt;li&gt;GroupJoin, Join&lt;/li&gt;&lt;br /&gt;&lt;li&gt;All, Any&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Distinct&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Except&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Intersect&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Union&lt;/li&gt;&lt;br /&gt;&lt;li&gt;OrderBy, OrderByDescending, ThenBy, ThenByDescending&lt;/li&gt;&lt;br /&gt;&lt;li&gt;GroupBy&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Average&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Count, LongCount&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Max, Min, Sum&lt;/li&gt;&lt;br /&gt;&lt;li&gt;OfType, Cast&lt;/li&gt;&lt;br /&gt;&lt;li&gt;First, FirstOrDefault&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Skip, Take&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;Voici l'exemple d'une requête sélectionnant seulement les publications qui contiennent le mot "C#" dans leur titre :&lt;br /&gt;&lt;pre&gt;&lt;div name="code"&gt;&lt;br /&gt;var requete = from publication in bdd.Publication&lt;br /&gt;                         where publication.Titre.Contains("C#")&lt;br /&gt;                         select publication;&lt;br /&gt;&lt;/div&gt;&lt;/pre&gt;&lt;br /&gt;Pour plus d'informations sur les requêtes LinQ, je vous invite à lire l'&lt;a href="http://ftp-developpez.com/morpheus/linq/linq.pdf"&gt;article de Thomas Lebrun&lt;/a&gt;.&lt;br /&gt;Il est aussi possible de requêter la source de données grâce à Entity SQL. C'est un langage héritant du vocabulaire et de la grammaire de type SQL. Ce langage permet de récupérer des produits scalaires, des ensembles de résultat et des graphes d'objet. Pour une description du langage, veuillez vous référer à la &lt;a href="http://msdn.microsoft.com/fr-fr/library/bb387145.aspx"&gt;documentation officielle&lt;/a&gt;.&lt;br /&gt;Voici l'exemple d'une requête récupérant toutes les publications stockées en base :&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;div name="code"&gt;&lt;br /&gt;string chaineRequete = "SELECT VALUE p FROM Publication AS p";&lt;br /&gt;&lt;br /&gt;// Définition de la requête de type ObjectQuery&amp;lt;Publication&amp;gt;&lt;br /&gt;ObjectQuery&amp;lt;Publication&amp;gt; requete = new ObjectQuery&amp;lt;Publication&amp;gt;(chaineRequete, bdd, MergeOption.NoTracking);&lt;br /&gt;&lt;/div&gt;&lt;/pre&gt;&lt;br /&gt;En dernier choix, vous pouvez utiliser les méthodes du générateur de requêtes de la classe "ObjectQuery&amp;lt;T&amp;gt;". En voici un exemple :&lt;br /&gt;&lt;pre&gt;&lt;div name="code"&gt;&lt;br /&gt;// Définition de la requête de type ObjectQuery&amp;lt;Publication&amp;gt;&lt;br /&gt;var requete = bdd.Publication.SelectValue&amp;lt;Publication&amp;gt;("it");&lt;br /&gt;&lt;/div&gt;&lt;/pre&gt;&lt;br /&gt;La suite de l'article fera uniquement référence à LinQ to Entities, mais toutes les requêtes faites sur le modèle peuvent être réalisées avec Entity SQL ou grâce aux méthodes du générateur de requêtes de la classe "ObjectQuery&amp;lt;T&amp;gt;".&lt;br /&gt;Chaque entité en relation avec une autre possède une collection d'entités connexes. Cependant, celle-ci n'est pas initialisée par défaut. Pour naviguer vers ces entités, il est nécessaire de les charger explicitement :&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;soit en utilisant la méthode "Include" de "ObjectQuery&amp;lt;T&amp;gt;",&lt;/li&gt;&lt;br /&gt;&lt;li&gt;soit en utilisant la méthode "Load" appartenant à la classe "EntityReference&amp;lt;T&amp;gt;" ou à "EntityCollection&amp;lt;T&amp;gt;".&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;L'exemple suivant utilise la méthode "Include" pour récupérer explicitement, lors de la requête, l'éditeur et les auteurs associés aux publications :&lt;br /&gt;&lt;pre&gt;&lt;div name="code"&gt;&lt;br /&gt;using (Modele bdd = new Modele())&lt;br /&gt;{&lt;br /&gt;    var requete = from publication in bdd.Publication.Include("Auteur").Include("Editeur") select publication;&lt;br /&gt;       &lt;br /&gt;    requete.ToList().ForEach((Publication p) =&amp;gt;&lt;br /&gt;    {&lt;br /&gt;        Console.WriteLine("Publication : ID = {0}  Titre = {1}", p.Id, p.Titre);&lt;br /&gt;       &lt;br /&gt;        Console.WriteLine("     Editeur : ID = {0}  Nom = {1}", p.Editeur.Id, p.Editeur.Nom);&lt;br /&gt;           &lt;br /&gt;        p.Auteur.ToList().ForEach(a =&amp;gt; Console.WriteLine("     Auteur : ID = {0}  Nom = {1} {2}",a.Id,a.Prenom,a.Nom));&lt;br /&gt;    });&lt;br /&gt;}&lt;br /&gt;&lt;/div&gt;&lt;/pre&gt;&lt;br /&gt;Voici un autre exemple avec l'utilisation de la méthode "Load". Remarquez que chaque collection ou chaque référence liée à une entité possède une propriété "IsLoaded" permettant de savoir si la ou les entités connexes sont chargées.&lt;br /&gt;&lt;pre&gt;&lt;div name="code"&gt;&lt;br /&gt;using (Modele bdd = new Modele())&lt;br /&gt;{&lt;br /&gt;    var requete = from publication in bdd.Publication select publication;&lt;br /&gt;&lt;br /&gt;    requete.ToList().ForEach((Publication p) =&amp;gt;&lt;br /&gt;    {&lt;br /&gt;        if (!p.EditeurReference.IsLoaded)&lt;br /&gt;            p.EditeurReference.Load();&lt;br /&gt;&lt;br /&gt;        Console.WriteLine("     Editeur : ID = {0}  Nom = {1}", p.Editeur.Id, p.Editeur.Nom);&lt;br /&gt;&lt;br /&gt;        if (!p.Auteur.IsLoaded)&lt;br /&gt;            p.Auteur.Load();&lt;br /&gt;&lt;br /&gt;        p.Auteur.ToList().ForEach(a =&amp;gt; Console.WriteLine("     Auteur : ID = {0}  Nom = {1} {2}", a.Id,      a.Prenom, a.Nom));&lt;br /&gt;    });&lt;br /&gt;}&lt;br /&gt;&lt;/div&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3773144983876508185-3284186974878284205?l=populnet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://populnet.blogspot.com/feeds/3284186974878284205/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3773144983876508185&amp;postID=3284186974878284205' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3773144983876508185/posts/default/3284186974878284205'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3773144983876508185/posts/default/3284186974878284205'/><link rel='alternate' type='text/html' href='http://populnet.blogspot.com/2008/11/lecture-des-donnes.html' title='Lecture des données'/><author><name>Popul</name><uri>http://www.blogger.com/profile/13339110117970769017</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://2.bp.blogspot.com/__831xq1hNEM/SXSGahZtTOI/AAAAAAAAAC0/YTZpJgy1wUI/S220/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3773144983876508185.post-3670292884444652167</id><published>2008-11-23T13:06:00.000+01:00</published><updated>2008-11-30T13:38:45.246+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Entity Framework'/><title type='text'>Quels sont les SGBDR supportés ?</title><content type='html'>La couche "Object Services" d'Entity Framework s'appuie sur le fournisseur de données "EntityClient" pour qu'il exécute les requêtes LinQ transformées au préalable en arbres d'expression. "EntityClient" a pour but d'accéder aux données définies dans le modèle EDM décrits par les 3 fichiers CSDL, MSL et SSDL. Il génère ensuite un arbre d'expressions relatif aux données du schéma logique et l'envoie à un fournisseur de données spécialisées, afin que celui-ci transforme l'arbre en requêtes SQL.&lt;br /&gt;&lt;br /&gt;Ce dernier fournisseur de données est spécifique à la base de données utilisée. Le fournisseur utilisé est défini par la chaine de connexion utilisée par l'objet "EntityConnection", qui a la responsable d'ouvrir la connexion de la source de données.&lt;br /&gt;&lt;br /&gt;Voici un exemple de chaine de connexion, définit par l'assistant de Visual Studio 2008 :&lt;br /&gt;&lt;pre&gt;&lt;div style="border:1px solid black;overflow:auto;"&gt;metadata=res://*/modele.csdlres://*/modele.ssdlres://*/modele.msl;provider=System.Data.SqlClient;provider&lt;br /&gt;connection string="Data Source=TLS-LOG-PO-PMO\SQLEXPRESS;Initial Catalog=helloentityfx;Integrated Security=True;MultipleActiveResultSets=True"&lt;/div&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;La 1ère partie concerne les métadonnées de la connexion. On y voit la référence aux 3 schémas du modèle EDM, et du fournisseur de données utilisé pour la base de données. Ici, c'est la classe "System.Data.SqlClient" qui permet de communiquer avec une base de type SQL Serveur 2005.&lt;br /&gt;&lt;br /&gt;Il est donc possible de spécifier un autre fournisseur de données pour utiliser, par exemple, une base Oracle, MySQL ou PostgreSQL. Voici une liste non exhaustive des fournisseurs de données compatibles avec Entity Framework :&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Oracle : &lt;a href="http://devart.com/dotconnect/oracle/"&gt;http://devart.com/dotconnect/oracle/&lt;/a&gt; (payant)&lt;/li&gt;&lt;br /&gt;&lt;li&gt;MySQL : &lt;a href="http://devart.com/dotconnect/mysql/"&gt;http://devart.com/dotconnect/mysql/&lt;/a&gt; (payant)&lt;/li&gt;&lt;br /&gt;&lt;li&gt;PostgreSQL : &lt;a href="http://pgfoundry.org/frs/shownotes.php?release_id=1230"&gt;http://pgfoundry.org/frs/shownotes.php?release_id=1230&lt;/a&gt; (gratuit)&lt;/li&gt;&lt;br /&gt;&lt;li&gt;SQLite : &lt;a href="http://sqlite.phxsoftware.com/"&gt;http://sqlite.phxsoftware.com/&lt;/a&gt;, &lt;a href="http://devart.com/dotconnect/sqlite/"&gt;http://devart.com/dotconnect/sqlite/&lt;/a&gt; (gratuit) &lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Il est aussi possible de créer son propre fournisseur de données. Un &lt;a href="http://code.msdn.microsoft.com/EFSampleProvider"&gt;projet&lt;/a&gt; sur Codeplex fournit le code nécessaire.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3773144983876508185-3670292884444652167?l=populnet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://populnet.blogspot.com/feeds/3670292884444652167/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3773144983876508185&amp;postID=3670292884444652167' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3773144983876508185/posts/default/3670292884444652167'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3773144983876508185/posts/default/3670292884444652167'/><link rel='alternate' type='text/html' href='http://populnet.blogspot.com/2008/11/quels-sont-les-sgbdr-supports.html' title='Quels sont les SGBDR supportés ?'/><author><name>Popul</name><uri>http://www.blogger.com/profile/13339110117970769017</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://2.bp.blogspot.com/__831xq1hNEM/SXSGahZtTOI/AAAAAAAAAC0/YTZpJgy1wUI/S220/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3773144983876508185.post-3137754405805072618</id><published>2008-11-20T14:58:00.004+01:00</published><updated>2008-11-30T15:05:07.965+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Entity Framework'/><title type='text'>Concept d'Entity Framework</title><content type='html'>Entity Framework est la solution de mapping objet relationnel proposée par Microsoft. Son but est de fournir la couche d'abstraction nécessaire aux développeurs pour qu'ils n'accèdent plus directement à la base de données, mais par l'intermédiaire d'entités définies par un modèle appelé EDM (Entity Data Model).&lt;br /&gt;&lt;br /&gt;Ce modèle est divisé en 3 parties :&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;u&gt;Le schéma conceptuel :&lt;/u&gt; Il regroupe la définition des entités, des ensembles d'entités et des fonctions utilisées. Ces éléments sont définis dans un fichier XML appelé CSDL (Conceptual Schema Definition Language). &lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;u&gt;Le schéma logique :&lt;/u&gt; Celui-ci correspond à la définition des tables, vues et procédures stockées déclarées dans la base de données. Toutes ces informations sont regroupées dans un fichier XML appelé SSDL (Store Schema Definition Language). &lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;u&gt;Schéma de liaison :&lt;/u&gt; Il définit les liaisons entre le schéma conceptuel et le schéma logique. Il associe entre autre les entités déclarées dans le fichier CSDL aux tables définies dans le fichier SSDL. Ce mapping est inscrit dans le fichier XML MSL (Mapping Specification Language). &lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://3.bp.blogspot.com/__831xq1hNEM/STKcOG7yleI/AAAAAAAAACs/E1n6C9cs2X0/s1600-h/1.png"&gt;&lt;img style="TEXT-ALIGN: center; MARGIN: 0px auto 10px; WIDTH: 483px; DISPLAY: block; HEIGHT: 175px; CURSOR: hand" id="BLOGGER_PHOTO_ID_5274449879797765602" border="0" alt="" src="http://3.bp.blogspot.com/__831xq1hNEM/STKcOG7yleI/AAAAAAAAACs/E1n6C9cs2X0/s400/1.png" /&gt;&lt;/a&gt;&lt;br /&gt;Visual Studio 2008 SP1 intègre aussi un assistant permettant de générer un modèle EDM, et ce de manière graphique. Il ressemble assez à l'assistant LinQ to SQL pour les connaisseurs et il offre un confort d'utilisation bien meilleur que l'outil en ligne de commande, au détriment d'un certain manque de fonctionnalités.&lt;br /&gt;&lt;br /&gt;Par exemple, il n'est pas possible de définir de type complexe avec l'assistant, alors que "EdmGen.exe" le permet. Rassurez-vous, vous pouvez commencer à utiliser l'assistant (gain de temps évident) et utiliser par la suite l'outil en ligne de commande. Néanmoins, il s'avère regrettable d'avoir recours à ce genre de manipulation. La prochaine version de l'assistant devrait corriger cela; et bien d'autres points.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3773144983876508185-3137754405805072618?l=populnet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://populnet.blogspot.com/feeds/3137754405805072618/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3773144983876508185&amp;postID=3137754405805072618' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3773144983876508185/posts/default/3137754405805072618'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3773144983876508185/posts/default/3137754405805072618'/><link rel='alternate' type='text/html' href='http://populnet.blogspot.com/2008/11/entity-framework-est-la-solution-de.html' title='Concept d&apos;Entity Framework'/><author><name>Popul</name><uri>http://www.blogger.com/profile/13339110117970769017</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://2.bp.blogspot.com/__831xq1hNEM/SXSGahZtTOI/AAAAAAAAAC0/YTZpJgy1wUI/S220/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/__831xq1hNEM/STKcOG7yleI/AAAAAAAAACs/E1n6C9cs2X0/s72-c/1.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3773144983876508185.post-8604145041543330154</id><published>2008-11-10T13:36:00.012+01:00</published><updated>2008-11-10T16:54:08.409+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='divers'/><title type='text'>Afficher correctement du code dans vos blogs</title><content type='html'>Dernièrement, j'ai cherché une manière d'afficher correctement du code sur mon blog. En cherchant un petit peu, j'ai trouvé la balise HTML &amp;lt;pre&amp;gt; qui garde l'indentation des lignes. Rien qu'avec cela, le code publié est déjà beaucoup plus lisible. En voici un exemple :&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;using System.Collections.Generic;&lt;br /&gt;&lt;br /&gt;namespace HelloWorld&lt;br /&gt;{&lt;br /&gt;  class Program&lt;br /&gt;  {&lt;br /&gt;      static void Main(string[] args)&lt;br /&gt;      {&lt;br /&gt;          using(WorkflowRuntime workflowRuntime = new WorkflowRuntime())&lt;br /&gt;          {&lt;br /&gt;              AutoResetEvent waitHandle = new AutoResetEvent(false);&lt;br /&gt;              workflowRuntime.WorkflowCompleted += delegate(object sender, WorkflowCompletedEventArgs e) {waitHandle.Set();};&lt;br /&gt;              workflowRuntime.WorkflowTerminated += delegate(object sender, WorkflowTerminatedEventArgs e)&lt;br /&gt;              {&lt;br /&gt;                  Console.WriteLine(e.Exception.Message);&lt;br /&gt;                  waitHandle.Set();&lt;br /&gt;              };&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Malheureusement, je n'ai pas trouvé de script ou d'addin fournissant une solution "clé en main" de mise en forme du code, supportant la colorisation de mots clés et l'indentation. Je vous propose donc un petit bout de code Javascript permettant de faire cela.&lt;br /&gt;&lt;br /&gt;Voici les objectifs du script de mise en forme:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;Rechercher toutes les balises ayant l'attribut &lt;span style="font-style: italic;"&gt;name&lt;/span&gt; comportant la valeur &lt;span style="font-style: italic;"&gt;code&lt;/span&gt; et appliquer la fonction &lt;span style="font-style: italic;"&gt;formatterElement&lt;/span&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;La fonction &lt;span style="font-style: italic;"&gt;formatterElement&lt;/span&gt; recherche l'ensemble des mots clés fournit par le tableau &lt;span style="font-style: italic;"&gt;motCles&lt;/span&gt; et rajoute autour la balise &lt;span style="font-style: italic;"&gt;&amp;lt;span class="motcle"&amp;gt; mot clé &amp;lt;/span&amp;gt;&lt;/span&gt;&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;Pour installer le script sur un blog de type Blogspot, copiez les styles CSS et les fonctions Javascript suivants quelque part dans la balise head de votre modèle.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&amp;lt;style type="text/css"&amp;gt;&lt;br /&gt;    div.code&lt;br /&gt;    {&lt;br /&gt;     background : #F0F0F0;&lt;br /&gt;     border: 1px solid black;&lt;br /&gt;     padding:5px;&lt;br /&gt;     margin:5px;&lt;br /&gt;    }&lt;br /&gt;    span.motcle&lt;br /&gt;    {&lt;br /&gt;     color:Blue;&lt;br /&gt;    }&lt;br /&gt;&amp;lt;/style&amp;gt;&lt;br /&gt;&amp;lt;script type="text/javascript"&amp;gt;&lt;br /&gt;    var regexpEchampement = unescape("([ \(\)\{\},\t\n\r%3C%3E\[;&amp;])");&lt;br /&gt;    var motsCles = [&lt;br /&gt;                    "public",&lt;br /&gt;                    "private",&lt;br /&gt;                    "protected",&lt;br /&gt;                    "sealed",&lt;br /&gt;                    "partial",&lt;br /&gt;                    "static",&lt;br /&gt;                    "class",&lt;br /&gt;                    "struct",&lt;br /&gt;                    "interface",&lt;br /&gt;                    "using",&lt;br /&gt;                    "namespace",&lt;br /&gt;                    "object",&lt;br /&gt;                    "string",&lt;br /&gt;                    "int",&lt;br /&gt;                    "bool",&lt;br /&gt;                    "float",&lt;br /&gt;                    "double",&lt;br /&gt;                    "decimal",&lt;br /&gt;                    "void",&lt;br /&gt;                    "in",&lt;br /&gt;                    "out",&lt;br /&gt;                    "extern",&lt;br /&gt;                    "true",&lt;br /&gt;                    "false",&lt;br /&gt;                    "new",&lt;br /&gt;                    "if",&lt;br /&gt;                    "for",&lt;br /&gt;                    "foreach",&lt;br /&gt;                    "throw",&lt;br /&gt;                    "while",&lt;br /&gt;                    "return",&lt;br /&gt;                    "case",&lt;br /&gt;                    "break",&lt;br /&gt;                    "try",&lt;br /&gt;                    "catch",&lt;br /&gt;                    "finally",&lt;br /&gt;                    "get",&lt;br /&gt;                    "set",&lt;br /&gt;                    "typeof",&lt;br /&gt;                    "delegate"&lt;br /&gt;                    ];&lt;br /&gt;&lt;br /&gt;    function formatterElements(nameElement) {&lt;br /&gt;        var codeElements = document.getElementsByName(nameElement);&lt;br /&gt;        eval(unescape("for (var j = 0; j %3C codeElements.length; j++) { formatterElement(codeElements[j]); }"));&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    function formatterElement(element) {&lt;br /&gt;        element.className = "code";&lt;br /&gt;&lt;br /&gt;        var code = null;&lt;br /&gt;        if ("outerHTML" in element) {&lt;br /&gt;        }&lt;br /&gt;        else {&lt;br /&gt;            code = element.innerHTML;&lt;br /&gt;&lt;br /&gt;            var loop = "for ( var i = 0 ; i %3C motsCles.length ; i++) { var reg = new RegExp(regexpEchampement + \"(\" + motsCles[i] + \")\" + regexpEchampement, \"g\"); code = code.replace(reg, unescape(\"%241%3Cspan%20class%3D%27motcle%27%3E%242%3C/span%3E%243\"));}";&lt;br /&gt;            eval(unescape(loop));&lt;br /&gt;&lt;br /&gt;            element.innerHTML = code;&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&amp;lt;/script&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Remarquez que le tableau &lt;span style="font-style:italic;"&gt;motsCles&lt;/span&gt; contient pas mal de mots clés du langage C#. Libre à vous d'ajouter/supprimer des mots clés. De même, vous pouvez aussi modifier les 2 styles CSS.&lt;br /&gt;&lt;br /&gt;Ensuite, ajoutez ce petit bout de javascript juste avant la fermeture de la balise body (&amp;lt;/body&amp;gt;):&lt;br /&gt;&amp;lt;script type="text/javascript"&amp;gt;&lt;br /&gt;    formatterElements("code");&lt;br /&gt;&amp;lt;/script&amp;gt;&lt;br /&gt;&lt;br /&gt;Voila le script est installé.&lt;br /&gt;Pour l'utiliser, il suffit juste d'ajouter une balise pre et une balise div ou autre avec l'attribut &lt;span style="font-style:italic;"&gt;name&lt;/span&gt; (ainsi que id="code", à cause de la méthode getElementByName d'IE qui regarde uniquement l'id des éléments) contenant la valeur &lt;span style="font-style:italic;"&gt;code&lt;/span&gt;. Exemple :&lt;br /&gt;&lt;br /&gt;&amp;lt;pre&amp;gt;&amp;lt;div name="code" id="code" &amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;public Impersonation(string pIdentifiant, string pMotDePasse, string pDomaine )&lt;br /&gt;{&lt;br /&gt;    _identifiant = pIdentifiant;&lt;br /&gt;    _motDePasse = pMotDePasse;&lt;br /&gt;    _domaine = pDomaine;&lt;br /&gt;}&lt;br /&gt;&amp;lt;/div&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;&lt;br /&gt;Ce qui donne :&lt;br /&gt;&lt;pre&gt;&lt;div name="code" id="code"&gt;&lt;br /&gt;public Impersonation(string pIdentifiant, string pMotDePasse, string pDomaine )&lt;br /&gt;{&lt;br /&gt;    _identifiant = pIdentifiant;&lt;br /&gt;    _motDePasse = pMotDePasse;&lt;br /&gt;    _domaine = pDomaine;&lt;br /&gt;}&lt;/div&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;EDIT :&lt;/span&gt; Pour l'instant, le script fonctionne à merveille sous Firefox, mais ne fonctionne pas vraiment sous IE 7/8. Cela vient du fait que toute affectation de la variable innerHtml d'un élément sous Internet Explorer normalise la chaine de caractères, et enlève l'ensemble tous les retours à la ligne et les espaces de plus de 2 caractères. Pour l'instant, je n'ai pas trouvé de contournement ...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3773144983876508185-8604145041543330154?l=populnet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://populnet.blogspot.com/feeds/8604145041543330154/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3773144983876508185&amp;postID=8604145041543330154' title='3 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3773144983876508185/posts/default/8604145041543330154'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3773144983876508185/posts/default/8604145041543330154'/><link rel='alternate' type='text/html' href='http://populnet.blogspot.com/2008/11/afficher-correctement-du-code-dans-vos.html' title='Afficher correctement du code dans vos blogs'/><author><name>Popul</name><uri>http://www.blogger.com/profile/13339110117970769017</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://2.bp.blogspot.com/__831xq1hNEM/SXSGahZtTOI/AAAAAAAAAC0/YTZpJgy1wUI/S220/photo.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3773144983876508185.post-2038328071218514006</id><published>2008-11-06T11:58:00.003+01:00</published><updated>2009-01-20T17:29:34.045+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Developpez.com'/><title type='text'>1er article sur Developpez.com</title><content type='html'>Ca y est !&lt;br /&gt;&lt;br /&gt;Mon &lt;a href="http://pmusso.developpez.com/tutoriels/dotnet/visual-studio/custom-tool/"&gt;1er article&lt;/a&gt; sur &lt;a href="http://www.developpez.com/"&gt;Developpez.com&lt;/a&gt; vient d'être publié hier.&lt;br /&gt;Il traite de la génération de code dans Visual Studio 2008 et plus particulièrement de la création d'un Custom Tool. Celui-ci créé à partir d'un fichier XML (ici, un fichier de configuration Sharepoint) une classe associée. Cette dernière peut être utilisée pour récupérer facilement des GUID, chose très utile dans la programmation Sharepoint.&lt;br /&gt;&lt;br /&gt;A noter que la classe est générée à l'aide de l'API CodeDom. Une autre alternative aurait été de générer la classe à partir d'une feuille XSLT.&lt;br /&gt;&lt;br /&gt;En tout cas, merci à l'équipe de Developpez et surtout à &lt;a href="http://blog.developpez.com/lgmorand"&gt;Louis-Guillaume Morand&lt;/a&gt;, responsable de la section .Net, qui m'a aidé dans la publication et mon intégration dans l'équipe de rédaction du site.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3773144983876508185-2038328071218514006?l=populnet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://pmusso.developpez.com/tutoriels/dotnet/visual-studio/custom-tool/' title='1er article sur Developpez.com'/><link rel='replies' type='application/atom+xml' href='http://populnet.blogspot.com/feeds/2038328071218514006/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3773144983876508185&amp;postID=2038328071218514006' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3773144983876508185/posts/default/2038328071218514006'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3773144983876508185/posts/default/2038328071218514006'/><link rel='alternate' type='text/html' href='http://populnet.blogspot.com/2008/11/1er-article-sur-developpezcom.html' title='1er article sur Developpez.com'/><author><name>Popul</name><uri>http://www.blogger.com/profile/13339110117970769017</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://2.bp.blogspot.com/__831xq1hNEM/SXSGahZtTOI/AAAAAAAAAC0/YTZpJgy1wUI/S220/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3773144983876508185.post-4993123139926729708</id><published>2008-11-05T13:29:00.021+01:00</published><updated>2008-11-12T14:51:08.854+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><title type='text'>Droits insuffisants, pensez Impersonation !</title><content type='html'>Bien souvent, lorsque l'on développe une application web ou même parfois une application Windows (Winforms, WPF, ...), le compte Windows utilisé par l'application ne possède pas les droits suffisants pour effectuer des actions sur le système de fichier, le domaine, la base de données ou sur tout autre système.&lt;br /&gt;&lt;br /&gt;Vous avez toujours la possibilité de modifier le compte utilisé. Par exemple, pour une application ASP.Net hébergé dans IIS, il est possible de changer le compte dans les paramètres du pool d'application. Cependant, ce n'est pas forcément une bonne solution. Cela peut même casser votre système d'authentification si celui-ci est de type Windows.&lt;br /&gt;&lt;br /&gt;Il est aussi possible d'ajouter les droits nécessaires au compte utilisé par l'application. Mais cela est bien souvent maladroit. Le compte utilisé pour une application ASP.Net est par défaut "Service réseau". Il peut paraître indélicat d'ajouter des droits de d'ajout ou de suppression de dossier à ce compte. Une autre application web utilisant ce compte pourrait être détournée intentionnellement pour supprimer, modifier ou récupérer des données importantes ...&lt;br /&gt;&lt;br /&gt;Une bonne solution est d'utiliser l'impersonation. Cela consiste à changer le compte utilisé pour exécuter la logique de votre application par un compte qui possède les droits nécessaires, c'est à dire un compte de service. Pour réaliser ceci, voici une petite classe utilitaire :&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;div name="code"&gt;&lt;br /&gt;using System;&lt;br /&gt;using System.Runtime.InteropServices;&lt;br /&gt;using System.Security.Principal;&lt;br /&gt;      &lt;br /&gt;public class Impersonation&lt;br /&gt;{&lt;br /&gt;          [DllImport("advapi32", SetLastError = true)]&lt;br /&gt;          private static extern bool LogonUser(string pUserName, string pDomaine, string pMotDePasse,&lt;br /&gt;                                                                                                                                         int pLogonType, int pLogonProvider, out IntPtr pJeton);&lt;br /&gt;          [DllImport("advapi32", CharSet = CharSet.Auto)]&lt;br /&gt;          private static extern bool CloseHandle(IntPtr pHandle);&lt;br /&gt;          private string _identifiant;&lt;br /&gt;          private string _motDePasse;&lt;br /&gt;          private string _domaine;&lt;br /&gt;          private WindowsImpersonationContext _impContext;&lt;br /&gt;&lt;br /&gt;          public Impersonation(string pIdentifiant, string pMotDePasse, string pDomaine )&lt;br /&gt;          {&lt;br /&gt;                     _identifiant = pIdentifiant;&lt;br /&gt;                     _motDePasse = pMotDePasse;&lt;br /&gt;                     _domaine = pDomaine;&lt;br /&gt;          }&lt;br /&gt;&lt;br /&gt;          public void Impersonifier()&lt;br /&gt;          {&lt;br /&gt;                     IntPtr handle = new IntPtr(0);&lt;br /&gt;                     if (!LogonUser(_identifiant, _domaine, _motDePasse, 3, 0, out handle))&lt;br /&gt;                                throw new Exception("Erreur d'authentification");&lt;br /&gt;                     _impContext = new WindowsIdentity(handle).Impersonate();&lt;br /&gt;              CloseHandle(handle);&lt;br /&gt;          }&lt;br /&gt;&lt;br /&gt;          public void Fermer()&lt;br /&gt;          {&lt;br /&gt;                     _impContext.Undo();&lt;br /&gt;          }&lt;br /&gt;}&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Tout est articulé autour de la fonction LogonUser qui permet de récupérer un jeton d'authentification. Elle prend entre en paramètre l'identifiant, le mot de passe et le domaine d'un compte de domaine ou local (SAM).&lt;br /&gt;&lt;br /&gt;Voici maintenant un petit exemple d'utilisation :&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;div name="code"&gt;&lt;br /&gt;try&lt;br /&gt;{&lt;br /&gt;     Impersonation imp = new Impersonation("identifiant", "domaine.fr", "motdepasse}");&lt;br /&gt;     imp.Impersonifier();&lt;br /&gt;     try&lt;br /&gt;     {&lt;br /&gt;          // Votre code ncessitant des droits suprieurs&lt;br /&gt;     }&lt;br /&gt;     catch { }&lt;br /&gt;     finally&lt;br /&gt;     {&lt;br /&gt;          imp.Fermer();&lt;br /&gt;     }&lt;br /&gt;}&lt;br /&gt;catch { } &lt;/div&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3773144983876508185-4993123139926729708?l=populnet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://populnet.blogspot.com/feeds/4993123139926729708/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3773144983876508185&amp;postID=4993123139926729708' title='1 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3773144983876508185/posts/default/4993123139926729708'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3773144983876508185/posts/default/4993123139926729708'/><link rel='alternate' type='text/html' href='http://populnet.blogspot.com/2008/11/droits-insuffisants-pensez.html' title='Droits insuffisants, pensez Impersonation !'/><author><name>Popul</name><uri>http://www.blogger.com/profile/13339110117970769017</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://2.bp.blogspot.com/__831xq1hNEM/SXSGahZtTOI/AAAAAAAAAC0/YTZpJgy1wUI/S220/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3773144983876508185.post-4597423257048646022</id><published>2008-10-29T11:51:00.006+01:00</published><updated>2008-11-05T15:02:36.941+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><category scheme='http://www.blogger.com/atom/ns#' term='Visual Studio'/><title type='text'>C# 4 et Visual Studio 2010 CTP en téléchargement</title><content type='html'>A &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=922B4655-93D0-4476-BDA4-94CF5F8D4814&amp;amp;displaylang=en"&gt;l'adresse suivante&lt;/a&gt;, vous trouverez une image virtuelle (Virtual PC 2007 SP1) où est installé Visual Studio 2010 !&lt;br /&gt;&lt;br /&gt;La VM est découpée en plusieurs archives, d'un total de 8 Go. Une fois installée, l'image nécessite 75 Go d'espace libre, outch ! Mais bon, une fois passé ces petites contraintes, vous aurez l'immense privilège d'essayer C# 4 avec sa DLR, son nouveau mot clé &lt;em&gt;dynamic et&lt;/em&gt; la covariance et controvariance sur les interfaces (mot clés in et out), et bien d'autres surprises.&lt;br /&gt;&lt;br /&gt;Va falloir que je fasse de la place ...&lt;br /&gt;&lt;br /&gt;Bon téléchargement.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3773144983876508185-4597423257048646022?l=populnet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://populnet.blogspot.com/feeds/4597423257048646022/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3773144983876508185&amp;postID=4597423257048646022' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3773144983876508185/posts/default/4597423257048646022'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3773144983876508185/posts/default/4597423257048646022'/><link rel='alternate' type='text/html' href='http://populnet.blogspot.com/2008/10/c-4-et-visual-studio-2010-ctp-en.html' title='C# 4 et Visual Studio 2010 CTP en téléchargement'/><author><name>Popul</name><uri>http://www.blogger.com/profile/13339110117970769017</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://2.bp.blogspot.com/__831xq1hNEM/SXSGahZtTOI/AAAAAAAAAC0/YTZpJgy1wUI/S220/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3773144983876508185.post-4824418993488183534</id><published>2008-10-28T23:19:00.006+01:00</published><updated>2008-11-10T14:33:52.348+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Evenements'/><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><title type='text'>Contenu de la PDC 2008</title><content type='html'>La &lt;a href="http://www.microsoftpdc.com/"&gt;PDC 2008&lt;/a&gt; (Professional Developers Conference) s'est déroulée du 25 au 28 octobre. Durant ces 4 jours intensifs, ont été présentés les produits et technologies suivantes :&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;&lt;u&gt;C# 4.0 :&lt;/u&gt;&lt;/strong&gt; La version 1.0 introduisait le code managé, la 2.0 les generiques, la 3.0 LinQ, la version 4.0 introduit la programmation dynamique. Le type des objets peut être connu juste à l'exécution, c'est à dire comme dans un langage de script (php, javascript, python, etc ...). Ceci est possible grâce à la DLR (Dynamic Language Runtime). Cela fait déjà plus d'un an que l'on en parle, et le plus célèbre des projets est l'implémentation du langage python, &lt;a href="http://www.codeplex.com/IronPython"&gt;ironpython&lt;/a&gt;, dans la plateforme .Net. A l'instar de la CLR qui unifiait tous les langages de programmation statiques, la DLR unifie tous les langages dynamiques. Libre à vous de développer votre propre langage dynamique. C# 4.0 dispose d'un nouveau mot clé : dynamic. En substituant le type de votre objet par dynamic, le type de votre objet n'est connu qu'à l'exécution. &lt;em&gt;dynamic&lt;/em&gt; est particulièrement utile pour manipuler des objets créés par des scripts. Cela permet de mélanger programmation statique et dynamique au même endroit. Le créateur du C# fait d'ailleurs une démonstration bluffante en copiant/collant un morceau de Javascript dans du C#. Après avoir modifié quelques mots clés (function, var), le code compile et fonctionne. Il est aussi possible de définir des paramètres optionnels dans les méthodes, et de les spécifier en fournissant le nom du paramètre en question. Grâce au support des types dynamiques, des paramètres optionnels et nommés, l'utilisation des objets COM est grandement simplifiée. Anders Hejlsberg part d'un exemple d'automation Excel, et simplifie petit à petit tous les appels aux objets et aux méthodes servant à piloter Excel. La covariance et controvariance a été amélioré, cela fonctionne maintenant avec les génériques de manière statique (mot clé in et out). En dernier lieu, le compilateur C# a été revu sous la forme d'un service pouvant être appelé simplement à partir d'un programme quelconque. Anders montre ainsi une console compilant et exécutant chaque ligne entrée. Le résultat est le même qu'avec un langage de script, le temps de compilation en plus bien sûr. Pour plus de détails, voici le &lt;a href="http://channel9.msdn.com/pdc2008/TL16/"&gt;lien&lt;/a&gt; de la conférence.&lt;br /&gt;&lt;br /&gt;&lt;u&gt;&lt;strong&gt;Visual Studio 10 :&lt;/strong&gt;&lt;/u&gt; Toute l'interface de l'application est basée sur WPF. L'extensibilité a été fortement améliorée puisqu'il est possible d'intégrer des addins en copiant simplement l'assembly en question dans le répertoire prévu pour. Celui est pris en compte au prochain démarrage de l'IDE. Le designer pour Silverlight a aussi pris un coup de jeune et cela n'est pas un mal. Une gestion plus fine des fichiers de configuration a été mise en place, c'est à dire un par type de build (Debug, Release). D'ailleurs, voici &lt;a href="http://channel9.msdn.com/pdc2008/TL47/"&gt;l'url&lt;/a&gt; de la vidéo conférence.&lt;br /&gt;&lt;br /&gt;&lt;u&gt;&lt;strong&gt;Workflow Foundation : &lt;/strong&gt;&lt;/u&gt;Une de mes briques préférées du Framework 3.0 a subit un petit lifting. Tout d'abord, l'actuel designer qui a la particularité d'être horiblement lent a été refait, ceci devant régler ce petit problème de performance. Les performances des workflows à l'exécution ont été largement améliorées. A noter aussi, la persistance des workflows est maintenant totalement personnalisable.&lt;br /&gt;&lt;br /&gt;&lt;u&gt;&lt;strong&gt;WPF, ASP.Net MVC, Surface SDK, Live Mesh (Bureau virtuel), Windows 7, Windows Azure &lt;em&gt;:&lt;/em&gt;&lt;/strong&gt;&lt;/u&gt; Je vous invite à aller voir le &lt;a href="http://blog.developpez.com/index.php?blog=29&amp;amp;cat=1842"&gt;blog de Louis-Guillaume Morand &lt;/a&gt;pour plus de détails sur ces technologies et produits.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3773144983876508185-4824418993488183534?l=populnet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://populnet.blogspot.com/feeds/4824418993488183534/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3773144983876508185&amp;postID=4824418993488183534' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3773144983876508185/posts/default/4824418993488183534'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3773144983876508185/posts/default/4824418993488183534'/><link rel='alternate' type='text/html' href='http://populnet.blogspot.com/2008/10/contenu-de-la-pdc-2008.html' title='Contenu de la PDC 2008'/><author><name>Popul</name><uri>http://www.blogger.com/profile/13339110117970769017</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://2.bp.blogspot.com/__831xq1hNEM/SXSGahZtTOI/AAAAAAAAAC0/YTZpJgy1wUI/S220/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3773144983876508185.post-8973179192258791669</id><published>2008-10-21T11:32:00.014+02:00</published><updated>2008-11-10T13:22:44.482+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Workflow Foundation'/><title type='text'>Workflow Foundation : Hello World</title><content type='html'>Pour ne pas déroger à la tradition du HelloWorld, nous allons créer pour ce premier exemple, un workflow qui écrit HelloWorld et votre prénom dans la console. Cet exemple très simple a le mérite de décrire les étapes fondamentales du développement et de l'exécution d'un workflow séquentiel. On va donc voir comment créer un workflow avec un template de Visual Studio 2008 prêt à l'emploi. Nous verrons ensuite comment il est hébergé et exécuté grâce au moteur de workflow.&lt;br /&gt;&lt;br /&gt;Dans un premier temps, créez d'abord un nouveau projet dans une nouvelle solution. Choisissez le template "Sequential Workflow Console Application", nommez le projet "HelloWorld" et la solution "HelloWorldWorkflow". Le projet créé est de type Console comme laisse présager le titre du template.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/__831xq1hNEM/SP2h29OvT2I/AAAAAAAAACQ/3Dgc9ssX-z0/s1600-h/template.gif"&gt;&lt;img style="TEXT-ALIGN: center; MARGIN: 0px auto 10px; DISPLAY: block; CURSOR: hand" id="BLOGGER_PHOTO_ID_5259537905359998818" border="0" alt="" src="http://2.bp.blogspot.com/__831xq1hNEM/SP2h29OvT2I/AAAAAAAAACQ/3Dgc9ssX-z0/s400/template.gif" /&gt;&lt;/a&gt;&lt;br /&gt;Ce template crée un workflow s'appelant Workflow1 dans un fichier de type cs (j'ai oublié de dire que le langage utilisé est le c#). En cliquant sur le petit plus, vous voyez apparaître le fichier Workflow1.designer.cs qui est le fichier généré par le designer de Workflow. Comme dans d'autres éditeurs fournis par Visual Studio, la classe Workflow1 est partielle (mot clé partial avant le nom de la classe), ce qui permet de définir dans 2 fichiers séparés, voir plus, la classe en question. Cliquez droit sur Workflow1.cs, et en choisissant View Code, vous verrez l'autre partie de la classe définissant le workflow.&lt;br /&gt;&lt;br /&gt;Le template a aussi créé un fichier Program.cs qui contient le code nécessaire pour instancier et exécuter le workflow généré.&lt;br /&gt;&lt;br /&gt;Sur ce, revenez sur le designer, ouvrez la Toolbox (boite à outils) et faites glisser l'activité Code qui est de type CodeActivity. Déposez là dans le workflow. Vous devriez avoir le résultat suivant :&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;a href="http://2.bp.blogspot.com/__831xq1hNEM/SP2h3N3-bII/AAAAAAAAACY/U8IWSb2O8gY/s1600-h/Workflow.gif"&gt;&lt;img style="TEXT-ALIGN: center; MARGIN: 0px auto 10px; DISPLAY: block; CURSOR: hand" id="BLOGGER_PHOTO_ID_5259537909827923074" border="0" alt="" src="http://2.bp.blogspot.com/__831xq1hNEM/SP2h3N3-bII/AAAAAAAAACY/U8IWSb2O8gY/s400/Workflow.gif" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Voila, nous venons d'insérer notre 1ere activité dans un workflow. Cette activité a pour but d'exécuter la logique métier que vous devez définir par l'intermédiaire d'une méthode. D'ailleurs, vous avez surement du remarquer le point d'exclamation dans le rond rouge en haut à droite de l'activité. Il signifie que justement, nous n'avons pas encore défini la méthode à exécuter et qu'il est nécessaire de le faire. Pour cela, double cliquez sur l'activité. Cela a pour effet de créer une méthode nommée "codeActivity1_ExecuteCode" et d'afficher le code de la classe Workflow1.cs. Dans l'autre partie de la classe générée par le designer, cela a instancié un délégué qui prend en argument la méthode précédemment créée et ce délégué est ajouté à l'événement ExecuteCode de l'activité.&lt;/p&gt;&lt;p&gt;Définissons le code de la méthode codeActivity1_ExecuteCode. Ce code va écrire dans la console "Hello World " suivi d'un nom qui sera passé en paramètre au workflow. Ajoutez d'abord la propriété Nom de type string comme cela :&lt;/p&gt;&lt;br /&gt;&lt;div name="code"&gt;&lt;br /&gt;public string Nom&lt;br /&gt;{&lt;br /&gt;    get;&lt;br /&gt;    set;&lt;br /&gt;}&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;Cette façon d'écrire une propriété, qui est une nouveauté du Framework 3.5, permet de générer à la fois l'accesseur (get), le mutateur (set) et le champ de type string associé. C'est un raccourci d'écriture qui est fort utile lorsque vous n'avez pas besoin de définir un comportement spécial pour le mutateur ou l’accesseur. Rajoutons ensuite la ligne suivante dans la méthode codeActivity1_ExecuteCode :&lt;/p&gt;&lt;br /&gt;&lt;div name="code"&gt;&lt;br /&gt;private void codeActivity1_ExecuteCode(object sender, EventArgs e)&lt;br /&gt;{&lt;br /&gt;    Console.WriteLine("Hello World " + Nom);&lt;br /&gt;}&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;Le workflow HelloWorld est terminé. Pour information, voici le code du workflow en entier (Workflow1.cs) :&lt;/p&gt;&lt;br /&gt;&lt;div name="code"&gt;&lt;br /&gt;using System;&lt;br /&gt;using System.Workflow.Activities;&lt;br /&gt;&lt;br /&gt;namespace HelloWorld&lt;br /&gt;{&lt;br /&gt;    public sealed partial class Workflow1: SequentialWorkflowActivity&lt;br /&gt;    {&lt;br /&gt;        public string Nom&lt;br /&gt;        {&lt;br /&gt;            get;&lt;br /&gt;            set;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        public Workflow1()&lt;br /&gt;        {&lt;br /&gt;            InitializeComponent();&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        private void codeActivity1_ExecuteCode(object sender, EventArgs e)&lt;br /&gt;        {&lt;br /&gt;            Console.WriteLine("Hello World " + Nom);&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;Tout d'abord le code généré dans la méthode Main qui est le point d'entrée de notre application console, sert à instancier et exécuter le workflow précédemment créé. Pour cela, nous devons d'abord instancier le moteur de workflow représenté par la classe System.Workflow.Runtime.WorkflowRuntime. Cette classe ou plutôt l'objet instancié de cette classe, fournit l'environnement d'exécution pour tous les workflows de l'application. Une seule instance de cette classe est autorisée par domaine d'application, comprenez par application pour simplifier. Il est bien évidemment possible de définir plusieurs domaines d'application dans une même application, mais ce n'est pas le sujet ici. Voici le code d'initialisation du moteur :&lt;/p&gt;&lt;br /&gt;&lt;div name="code"&gt;&lt;br /&gt;using(WorkflowRuntime workflowRuntime = new WorkflowRuntime())&lt;br /&gt;{&lt;br /&gt;}&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;L'instanciation du moteur est faite dans un bloc using (instanciation) {Suite d'instruction} car le moteur dérive de l'interface IDisposable, qui oblige la classe qui en hérite de définir une méthode Dispose. Celle-ci s'occupe de terminer l'exécution des workflows en cours et de libérer la mémoire utilisée. A la fin du bloc using, cette méthode est donc appelée implicitement. Toute nouvelle instruction prend place entre les accolades du using.&lt;/p&gt;&lt;p&gt;Poursuivons notre description. La ligne suivante déclare un objet de type System.Threading.AutoResetEvent et l'instancie :&lt;/p&gt;&lt;br /&gt;&lt;div name="code"&gt;&lt;br /&gt;AutoResetEvent waitHandle = new AutoResetEvent(false);&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;Cet objet est utile pour synchroniser 2 threads d'exécution. Il permet de stopper l'exécution d'un thread jusqu'à ce qu'un évènement particulier soit détecté, évènement déclenché dans un autre thread. Le thread déclenchant l'évènement le fait bien évidement au moment opportun, c'est-à-dire lorsqu'il a terminé ce qu'il a à faire. &lt;/p&gt;&lt;p&gt;Mais pourquoi avons-nous besoin d'un tel objet pour exécuter notre workflow HelloWorld ? Et bien, c'est simple. Le comportement par défaut du moteur de workflow est de créer un thread par workflow exécuté. Ce comportement est bien sûr modifiable, mais pour l'heure, nous ferons avec. Si nous exécutons notre workflow sans utiliser un objet AutoResetEvent, alors notre application instancie effectivement le workflow, le lance, ce qui crée un thread dédié où le workflow est exécuté. Cependant juste après la ligne lançant l'exécution du workflow, le flux d'exécution continuera sans attendre la fin du workflow, sortira ensuite du bloc using, ce qui appelera la méthode Dispose implicitement, qui aura pour effet de détruire l'instance du moteur et du workflow par la même occasion. Nous n'aurons même pas la chance de voir afficher notre "HelloWorld" dans la console. Avec un objet AutoResetEvent, cela nous permet d'attendre tranquillement la fin du workflow.&lt;/p&gt;&lt;p&gt;Définissons 2 délégués anonymes que l'on affectera à l'évènement WorkflowCompleted et WorkflowTerminated du moteur de workflow (ici workflowRuntime). Le 1er évènement est déclenché lorsqu'un workflow exécuté par le moteur se termine avec succès. L'autre, WorkflowTerminate, est déclenché lorsqu'un workflow se termine à cause d'une exception. Voici les 2 délégués :&lt;/p&gt;&lt;br /&gt;&lt;div name="code"&gt;&lt;br /&gt;workflowRuntime.WorkflowCompleted += delegate(object sender, WorkflowCompletedEventArgs e)&lt;br /&gt;{&lt;br /&gt;    waitHandle.Set();&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;workflowRuntime.WorkflowTerminated += delegate(object sender, WorkflowTerminatedEventArgs e)&lt;br /&gt;{&lt;br /&gt;    Console.WriteLine(e.Exception.Message);&lt;br /&gt;    waitHandle.Set();&lt;br /&gt;};&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;Chacun d'eux exécute la méthode Set() de l'objet waitHandle. Cette instruction marche de pair avec la méthode WaitOne() du même objet. Comme expliqué plus haut, un workflow est exécuté dans son propre thread. Ainsi pour attendre la fin du workflow, nous utilisons la méthode WaitOne() qui attend que la méthode Set() soit exécutée dans un autre thread.&lt;/p&gt;&lt;p&gt;Les 2 délégués sont donc exécutés par le thread du workflow. Leur exécution permet de poursuivre l'éxecution de notre programme principal (bloquée jusqu'alors par WaitOne() de l'objet waitHandle).&lt;br /&gt;&lt;br /&gt;Notez que le délégué associé à l'évènement WorkflowTerminated récupère l'erreur générée par le workflow et l'écrit dans la console.&lt;/p&gt;&lt;p&gt;A ce stade, il ne reste plus qu'à définir les arguments du workflow, c'est-à-dire le nom qui s'affichera à côté de "HelloWorld", de lancer le workflow et finalement d'attendre la fin de son exécution. Pour définir les arguments d'un workflow, WF permet d'utiliser une Hashtable ou Dictionnaire. Cette structure de données associe une valeur clé (ici de type string) avec un objet et cette association de données définie un élément du dictionnaire. Voici le code pour définir le paramètre de notre workflow :&lt;/p&gt;&lt;br /&gt;&lt;div name="code"&gt;Dictionary&amp;lt;string,object&amp;gt; arguments = new Dictionary&amp;lt;string,object&amp;gt;();&lt;br /&gt;arguments.Add("Nom", "John Connor");&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;Il est possible de remplacer le nom ci-dessus par l'un de votre choix, ceci n'a aucune incidence sur le bon fonctionnement du workflow. Lors de la définition de notre workflow, nous avons défini une propriété Nom dans la classe partielle du workflow. La clé de notre argument dans le dictionnaire a le même nom que cette propriété. En fait, lorsque l'on passe le dictionnaire au moteur pour instancier notre workflow, celui-ci va, après avoir instancié le workflow, chercher, via la réflexion, la propriété du workflow s'appelant exactement "Nom" et va lui donner la valeur, ici "John Connor" en la castant, vu que c'est un objet dans le dictionnaire.&lt;/p&gt;&lt;p&gt;Il ne reste plus qu'à instancier le workflow et le lancer avec les 2 instructions suivantes :&lt;/p&gt;&lt;br /&gt;&lt;div name="code"&gt;&lt;br /&gt;WorkflowInstance instance = workflowRuntime.CreateWorkflow(typeof(HelloWorld.Workflow1),arguments);&lt;br /&gt;instance.Start();&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;La méthode CreateWorkflow prend en argument le type du workflow et le dictionnaire définissant les arguments. Elle renvoie un objet de type WorkflowInstance qui contient la méthode Start() permettant d'exécuter le workflow. &lt;/p&gt;&lt;p&gt;Finalement, ajoutez les 2 lignes suivantes pour attendre la fin d'exécution du workflow et de laisser le choix à l'utilisateur de fermer le programme.&lt;/p&gt;&lt;br /&gt;&lt;div name="code"&gt;&lt;br /&gt;waitHandle.WaitOne();&lt;br /&gt;Console.ReadKey();&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;Si tout s'est bien passé, voici l'affichage que vous devriez avoir après avoir compilé et lancé le projet :&lt;/p&gt;&lt;p&gt;&lt;a href="http://4.bp.blogspot.com/__831xq1hNEM/SP2h3LjQyGI/AAAAAAAAACg/orQr1kqgc_c/s1600-h/resultat.gif"&gt;&lt;img style="TEXT-ALIGN: center; MARGIN: 0px auto 10px; DISPLAY: block; CURSOR: hand" id="BLOGGER_PHOTO_ID_5259537909204174946" border="0" alt="" src="http://4.bp.blogspot.com/__831xq1hNEM/SP2h3LjQyGI/AAAAAAAAACg/orQr1kqgc_c/s400/resultat.gif" /&gt;&lt;/a&gt;&lt;br /&gt;Pour une meilleure vision du code nécessaire à l'instanciation et l'exécution d'un workflow, voici l'intégralité du code :&lt;/p&gt;&lt;br /&gt;&lt;div name="code"&gt;&lt;br /&gt;using System;&lt;br /&gt;using System.Threading;&lt;br /&gt;using System.Workflow.Runtime;&lt;br /&gt;using System.Collections.Generic;&lt;br /&gt;&lt;br /&gt;namespace HelloWorld&lt;br /&gt;{&lt;br /&gt;    class Program&lt;br /&gt;    {&lt;br /&gt;        static void Main(string[] args)&lt;br /&gt;        {&lt;br /&gt;            using(WorkflowRuntime workflowRuntime = new WorkflowRuntime())&lt;br /&gt;            {&lt;br /&gt;                AutoResetEvent waitHandle = new AutoResetEvent(false);&lt;br /&gt;                workflowRuntime.WorkflowCompleted += delegate(object sender, WorkflowCompletedEventArgs e) {waitHandle.Set();};&lt;br /&gt;                workflowRuntime.WorkflowTerminated += delegate(object sender, WorkflowTerminatedEventArgs e)&lt;br /&gt;                {&lt;br /&gt;                    Console.WriteLine(e.Exception.Message);&lt;br /&gt;                    waitHandle.Set();&lt;br /&gt;                };&lt;br /&gt;&lt;br /&gt;                Dictionary&amp;lt;string,object&amp;gt; arguments = new Dictionary&amp;lt;string,object&gt;();&lt;br /&gt;                arguments.Add("Nom", "John Connor");&lt;br /&gt;&lt;br /&gt;                WorkflowInstance instance = workflowRuntime.CreateWorkflow(typeof(HelloWorld.Workflow1),arguments);&lt;br /&gt;                instance.Start();&lt;br /&gt;&lt;br /&gt;                waitHandle.WaitOne();&lt;br /&gt;&lt;br /&gt;                Console.ReadKey();&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3773144983876508185-8973179192258791669?l=populnet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://populnet.blogspot.com/feeds/8973179192258791669/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3773144983876508185&amp;postID=8973179192258791669' title='1 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3773144983876508185/posts/default/8973179192258791669'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3773144983876508185/posts/default/8973179192258791669'/><link rel='alternate' type='text/html' href='http://populnet.blogspot.com/2008/10/workflow-foundation-hello-world.html' title='Workflow Foundation : Hello World'/><author><name>Popul</name><uri>http://www.blogger.com/profile/13339110117970769017</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://2.bp.blogspot.com/__831xq1hNEM/SXSGahZtTOI/AAAAAAAAAC0/YTZpJgy1wUI/S220/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/__831xq1hNEM/SP2h29OvT2I/AAAAAAAAACQ/3Dgc9ssX-z0/s72-c/template.gif' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3773144983876508185.post-2380602671025394889</id><published>2008-10-16T11:09:00.009+02:00</published><updated>2008-11-05T15:03:29.677+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Sharepoint'/><title type='text'>Indexation MOSS : Faites attention à la page par défaut d'une collection de site</title><content type='html'>Actuellement, je travaille sur un portail intranet basé sur Sharepoint MOSS. Etant en phase d'intégration, je corrige les quelques bugs restants. L'un d'entre eux m'a particulièrement surpris concernant l'indexation d'une collection de site. Celle-ci s'arrêtait au bout de 3 items "crawlés", alors que la collection contient plus de 800 éléments à indexer.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/__831xq1hNEM/SPcI78cv0mI/AAAAAAAAACE/yezmQOQ5iK0/s1600-h/result_crawl.GIF"&gt;&lt;img style="TEXT-ALIGN: center; MARGIN: 0px auto 10px; DISPLAY: block; CURSOR: hand" id="BLOGGER_PHOTO_ID_5257680915910349410" border="0" alt="" src="http://4.bp.blogspot.com/__831xq1hNEM/SPcI78cv0mI/AAAAAAAAACE/yezmQOQ5iK0/s400/result_crawl.GIF" /&gt;&lt;/a&gt; Après une petite recherche dans les logs applicatifs du serveur, je suis tombé sur une erreur de type Warning, ASP.NET 2.0.50727.0, WebEvent :&lt;br /&gt;&lt;div&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;a href="http://1.bp.blogspot.com/__831xq1hNEM/SPcIxAFDzoI/AAAAAAAAAB8/ENI-_uv0O-o/s1600-h/app_log.GIF"&gt;&lt;img style="TEXT-ALIGN: center; MARGIN: 0px auto 10px; DISPLAY: block; CURSOR: hand" id="BLOGGER_PHOTO_ID_5257680727906176642" border="0" alt="" src="http://1.bp.blogspot.com/__831xq1hNEM/SPcIxAFDzoI/AAAAAAAAAB8/ENI-_uv0O-o/s400/app_log.GIF" /&gt;&lt;/a&gt;&lt;/div&gt;Je remarque que dans les Request Information la page d'accueil (page par défaut) de la collection de site renvoie une exception de type NullReferenceException. Pourtant, dans la définition des sources à indexer, seuls 2 sous sites ont été spécifiés. La page par défaut ne devrait pas être indexée. Pour vérifier que la page par défaut de la collection de site est en cause, j'ai donc spécifié une autre page par défaut grace à une page Layout uniquement accessible par URL : [url collection de site]/_Layouts/AreaWelcomePage.aspx.&lt;br /&gt;&lt;br /&gt;Après avoir effectuer la manipulation et relancer le crawl, tout est rentré dans l'ordre. J'ai donc du modifier la page par défaut en éditant un script C# codé de manière inline dans la page par défaut de la collection de site.&lt;br /&gt;&lt;br /&gt;Moralité, faites attention à la page par défaut de votre collection de sites si vous souhaitez indexer le contenu des sous sites.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3773144983876508185-2380602671025394889?l=populnet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://populnet.blogspot.com/feeds/2380602671025394889/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3773144983876508185&amp;postID=2380602671025394889' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3773144983876508185/posts/default/2380602671025394889'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3773144983876508185/posts/default/2380602671025394889'/><link rel='alternate' type='text/html' href='http://populnet.blogspot.com/2008/10/indexation-moss-faites-attention-la.html' title='Indexation MOSS : Faites attention à la page par défaut d&apos;une collection de site'/><author><name>Popul</name><uri>http://www.blogger.com/profile/13339110117970769017</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://2.bp.blogspot.com/__831xq1hNEM/SXSGahZtTOI/AAAAAAAAAC0/YTZpJgy1wUI/S220/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/__831xq1hNEM/SPcI78cv0mI/AAAAAAAAACE/yezmQOQ5iK0/s72-c/result_crawl.GIF' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3773144983876508185.post-4598603943711694300</id><published>2008-10-08T13:17:00.004+02:00</published><updated>2008-10-08T14:00:58.899+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Workflow Foundation'/><title type='text'>Qu'est ce qu'un workflow ?</title><content type='html'>&lt;div align="justify"&gt;Pour répondre à cette question, je vais faire l'analogie avec le code d'un développeur. Lorsque l'on développe, on définit le plus souvent une suite d'opérations ou de tâches. Cela peut être une insertion dans un journal d'événements ou dans une base de données. Ensuite, on ordonne ces opérations avec des instructions qui contrôlent le flux de notre programme. Par exemple, on utilise l'instruction :&lt;/div&gt;&lt;br /&gt;&lt;em&gt;If (condition)&lt;br /&gt;{Liste d'opération 1}&lt;br /&gt;else {Liste d'opération 2} &lt;/em&gt;&lt;br /&gt;&lt;br /&gt;ou un bloc :&lt;br /&gt;&lt;br /&gt;&lt;em&gt;While (Condition)&lt;br /&gt;{Liste d'opérations}&lt;/em&gt;&lt;br /&gt;&lt;br /&gt;pour traiter des données en boucle.&lt;br /&gt;&lt;br /&gt;&lt;div align="justify"&gt;Chaque décision dans le code, que ce soit en C#, Java, C/C++, Javascript etc ..., est matérialisée par des conditions. Tout code source possède 3 types d'instruction:&lt;/div&gt;&lt;ul&gt;&lt;li&gt;&lt;div align="justify"&gt;&lt;strong&gt;Les instructions d'exécution&lt;/strong&gt; qui peuvent être une écriture dans une base de données ou encore dans un journal d'évènements, l'envoi d'un mail, ou plus généralement toute instruction qui exécute une action.&lt;/div&gt;&lt;/li&gt;&lt;li&gt;&lt;div align="justify"&gt;&lt;strong&gt;Les instructions définissant le flux d'exécution&lt;/strong&gt; comme le bloc &lt;em&gt;if (condition) {instructions} else {instructions}&lt;/em&gt;. Ce sont toutes les instructions qui ont une influence sur le flux d'exécution du programme.&lt;/div&gt;&lt;/li&gt;&lt;li&gt;&lt;div align="justify"&gt;&lt;strong&gt;Les règles&lt;/strong&gt; qui définissent les conditions dans les flux d'exécution.&lt;/div&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p align="justify"&gt;Voici un exemple montrant les 3 types les 3 types d'instruction:&lt;/p&gt;&lt;div align="justify"&gt;&lt;a href="http://3.bp.blogspot.com/__831xq1hNEM/SOyZC0KxDuI/AAAAAAAAAAs/E3Mi_OxQ8EI/s1600-h/image1.png"&gt;&lt;img style="TEXT-ALIGN: center; MARGIN: 0px auto 10px; WIDTH: 500px; DISPLAY: block; HEIGHT: 258px; CURSOR: hand" id="BLOGGER_PHOTO_ID_5254743138877116130" border="0" alt="" src="http://3.bp.blogspot.com/__831xq1hNEM/SOyZC0KxDuI/AAAAAAAAAAs/E3Mi_OxQ8EI/s320/image1.png" width="419" height="204" /&gt;&lt;/a&gt;Les concepteurs de Workflow Foundation ont identifié ces 3 concepts et les ont intégrés dans Workflow Foundation. Un workflow n'est rien d'autre qu'une suite d'instructions d'exécution représentée par des activités (&lt;em&gt;Custom Activity, Code Activity, InvokeWebService&lt;/em&gt;, etc…). Ces instructions d'exécution ou activités sont elles-mêmes comprises dans des activités définissant le flux d'exécution du programme (&lt;em&gt;IfElseActivity, WhileActivity, ParallelActivity, ReplicatorActivity&lt;/em&gt;, etc…). Pour définir les conditions dans les activités définissant le flux d'exécution, on met en place des règles (rules en anglais). Pour illustrer cela, voici un workflow reprenant la même logique que l'exemple précédent :&lt;/div&gt;&lt;div align="justify"&gt;&lt;a href="http://1.bp.blogspot.com/__831xq1hNEM/SOyZDFt6mgI/AAAAAAAAAA0/rhiWG9s1moo/s1600-h/image2.png"&gt;&lt;img style="TEXT-ALIGN: center; MARGIN: 0px auto 10px; WIDTH: 509px; DISPLAY: block; HEIGHT: 336px; CURSOR: hand" id="BLOGGER_PHOTO_ID_5254743143587944962" border="0" alt="" src="http://1.bp.blogspot.com/__831xq1hNEM/SOyZDFt6mgI/AAAAAAAAAA0/rhiWG9s1moo/s320/image2.png" width="448" height="291" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div align="justify"&gt;Premièrement, le workflow est représenté de manière graphique. Les deux exemples réalisent exactement la même chose. Cependant, dans le premier exemple, tout a été défini avec un langage textuel qui est le C# alors que dans le deuxième, tout a été quasiment définit de manière graphique en utilisant le drag'n drop et la fenêtre de propriété de Visual Studio 2008.&lt;br /&gt;Aujourd'hui, c'est dans l'air du temps d'utiliser ce que l'on appelle des langages graphiques ou des DSL (Domain Specific Language). Le plus célèbre d'entre eux est le designer de classes intégré dans toutes les éditions de Visual Studio. Workflow Foundation propose ainsi de définir votre propre langage graphique pour définir les workflows. Pour cela, nous avons à notre disposition un ensemble d'activités que l'on peut glisser et déplacer dans la fenêtre définissant le workflow. Voici un aperçu de la Toolbox regroupant les différentes activités fournies par WF :&lt;br /&gt;&lt;/div&gt;&lt;a href="http://2.bp.blogspot.com/__831xq1hNEM/SOyZDCN_RoI/AAAAAAAAAA8/xR544gBmDIw/s1600-h/image3.png"&gt;&lt;img style="TEXT-ALIGN: center; MARGIN: 0px auto 10px; WIDTH: 218px; DISPLAY: block; HEIGHT: 419px; CURSOR: hand" id="BLOGGER_PHOTO_ID_5254743142648727170" border="0" alt="" src="http://2.bp.blogspot.com/__831xq1hNEM/SOyZDCN_RoI/AAAAAAAAAA8/xR544gBmDIw/s320/image3.png" width="190" height="379" /&gt;&lt;/a&gt;&lt;br /&gt;Il est aussi possible de définir un workflow par le code, en instanciant les bons objets, ou avec du XAML (rebaptisé XOML dans WF, pour le différencier du XAML de WPF). Le XAML est un langage basé sur XML permettant d'instancier et de paramétrer des objets.&lt;br /&gt;Lorsqu'on crée un nouveau workflow, nous avons le choix avec 2 implémentations de workflow :&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Workflow basé sur du code uniquement&lt;/li&gt;&lt;li&gt;Workflow basé sur du XAML avec un fichier de code associé&lt;/li&gt;&lt;/ul&gt;&lt;p align="justify"&gt;Théoriquement, il est aussi possible définir un workflow basé uniquement sur du XAML en supprimant le fichier de code associé, Visual Studio 2005 ou 2008 ne propose pas ce template. L'intérêt principal d'un workflow définit uniquement en XAML, est que l'on peut le modifier à la main ou via un éditeur spécialisé sans avoir besoin de recompiler l'application. Cela laisse penser qu'il est possible développer des applications avec des workflows, et que votre client pourra via un éditeur de workflow, modifier par la suite le comportement de son programme en éditant lui-même ses workflows. Bien sûr, il devra avoir une connaissance du vocabulaire métier défini dans le workflow, mais comme celui-ci est la matérialisation d'un processus de l'entreprise, cela devrait lui être familier. Dans tous les cas, c'est beaucoup plus simple et plus réaliste que de modifier du code et de le recompiler.&lt;br /&gt;Une autre différence fondamentale lorsqu'on utilise WF est que la logique définissant ce que l'on fait est séparée de la logique qui définit quand on le fait. C'est-à-dire que l'on peut changer toute la logique de séquencement ou d'ordonnancement d'un workflow sans affecter les instructions d'exécution. Pour cela, on sélectionne la ou les activités voulues et on les déplace à l'endroit souhaité dans le workflow. Avec un langage textuel, cela se résumerai à un ensemble de couper/coller quelque peu hasardeux et pas toujours très simple à réaliser.&lt;br /&gt;Comme la logique d'ordonnancement est définie de manière déclarative et qu'en fait chaque activité correspond à une classe, il est tout à fait possible de modifier à l'exécution, c'est-à-dire dynamiquement, un workflow. Par exemple, on peut rajouter de nouvelles instructions d'exécution ou des instructions définissant le flux d'exécution à un endroit donné. Il suffit simplement d'instancier les activités voulues, de les paramétrer et de les insérer là où on le souhaite. Comparé à un langage textuel, cela pourrait être synonyme d'injection de code (via de la POA par exemple), ce qui est quand même bien plus complexe à réaliser.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3773144983876508185-4598603943711694300?l=populnet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://populnet.blogspot.com/feeds/4598603943711694300/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3773144983876508185&amp;postID=4598603943711694300' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3773144983876508185/posts/default/4598603943711694300'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3773144983876508185/posts/default/4598603943711694300'/><link rel='alternate' type='text/html' href='http://populnet.blogspot.com/2008/10/quest-ce-quun-workflow.html' title='Qu&apos;est ce qu&apos;un workflow ?'/><author><name>Popul</name><uri>http://www.blogger.com/profile/13339110117970769017</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://2.bp.blogspot.com/__831xq1hNEM/SXSGahZtTOI/AAAAAAAAAC0/YTZpJgy1wUI/S220/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/__831xq1hNEM/SOyZC0KxDuI/AAAAAAAAAAs/E3Mi_OxQ8EI/s72-c/image1.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3773144983876508185.post-6451495580163878930</id><published>2008-10-05T19:01:00.007+02:00</published><updated>2008-11-05T15:03:47.190+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Visual Studio'/><title type='text'>Utiliser les Custom Tools dans Visual Studio</title><content type='html'>Alors déjà, qu'est ce qu'un Custom Tool ?&lt;br /&gt;C'est un utilitaire sous forme de librairie (dll) qu'utilise Visual Studio afin de générer quelque chose, généralement des classes, à partir d'un fichier en entrée. Chaque fichier présent dans une solution Visual Studio (2003,2005 et 2008) propose dans sa fenêtre de propriété un champ Custom Tool.&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/__831xq1hNEM/SOkOLGVnQVI/AAAAAAAAAAg/HxyrFplorQQ/s1600-h/prop.jpg"&gt;&lt;img id="BLOGGER_PHOTO_ID_5253746024147009874" style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="http://3.bp.blogspot.com/__831xq1hNEM/SOkOLGVnQVI/AAAAAAAAAAg/HxyrFplorQQ/s320/prop.jpg" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;div&gt;Sur un fichier de ressources de type resx, le Custom Tool &lt;em&gt;ResXFileCodeGenerator&lt;/em&gt; est défini d'office. Son rôle est de générer une classe contenant le code pour accéder aux différentes ressouces déclarées dans le fichier XML. Voici une liste regroupant les plus populaires :&lt;/div&gt;&lt;ul&gt;&lt;li&gt;MSDiscoCodeGenerator : Génère une classe proxy permettant d'accéder simplement à un web service à partir de son fichier wsdl&lt;/li&gt;&lt;li&gt;WCF Proxy Generator : A partir d'un fichier .svcmap, ce custom tool génère la classe d'accès au service&lt;/li&gt;&lt;li&gt;SettingsSingleFileGenerator et ResXFileCodeGenerator : Génère une classe proxy vers un fichier de configuration ou de ressources&lt;/li&gt;&lt;li&gt;EntityModelCodeGenerator : Génère l'ensemble des classes d'accès aux données (Entity Framework) à partir d'un fichier edmx&lt;/li&gt;&lt;li&gt;MSLinqToSQLGenerator : A l'instar de EntityModelCodeGenerator, ce custom tool s'occupe du fichier XML (.dbml) créé par le designer de LinQ to SQL. &lt;/li&gt;&lt;li&gt;MSDataSetGenerator : Créé un ensemble de fichier XML et de classes définissant un Dataset, à partir d'un fichier XSD&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;Les Custom Tools permettent de gagner un temps conséquent (plusieurs milliers de lignes de code peuvent être générées d'une passe) et garantissent une certaine qualité dans le code produit. Il est à noter que cela fonctionne que dans un seul sens (unidirectionnel). Modifiez un fichier généré par un Custom Tool et celui-ci sera écrasé à la prochaine génération.&lt;/div&gt;&lt;div&gt;Il est aussi intéressant de savoir que l'on peut redéfinir le Custom Tool attaché à n'importe quel fichier. Du coup, si le code créé par un Custom Tool ne vous plait pas, rien ne vous empêche de créer le votre et de l'attacher au fichier source. Sur le site suivant, vous trouverez une démonstration avec le WCF Proxy Generator : &lt;a href="http://blogs.msdn.com/pedram/archive/2007/08/10/customising-wcf-proxy-generation-in-visual-studio-2008.aspx"&gt;http://blogs.msdn.com/pedram/archive/2007/08/10/customising-wcf-proxy-generation-in-visual-studio-2008.aspx&lt;/a&gt;.&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;Alors comment savoir si vous avez besoin de créer votre propre Custom Tool ? Et bien, si vous avez un ou plusieurs fichiers XML dans vos projets C# ou VB .Net, et que vous devez créer du code pour accéder aux informations stockées dedans, un Custom Tool adapté vous permettra de vous passer de cette tâche un peu fastidieuse. Je les ai d'ailleurs utilisés pour un projet Sharepoint. Une solution typique WSS ou MOSS contient bien souvent un nombre impressionnant de fichiers XML (features, fields, ONET.XML, etc ...), et il est souvent utile de pouvoir accéder facilement à certaines de leurs informations.&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Voici quelques liens si vous souhaitez créer votre propre Custom Tool :&lt;/div&gt;&lt;ul&gt;&lt;li&gt;Pour Visual Studio 2005 &amp;amp; 2008 en français, en VB &amp;amp; C# : &lt;a href="http://gilles.tourreau.fr/dotnet/visual_studio/vs2005_2008_creation_dun_outil_personnalise_custom_tool.html"&gt;http://gilles.tourreau.fr/dotnet/visual_studio/vs2005_2008_creation_dun_outil_personnalise_custom_tool.html&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Pour Visual Studio 2005 en Anglais : &lt;a href="http://blogs.conchango.com/pauloreichert/archive/2005/05/21/1459.aspx"&gt;http://blogs.conchango.com/pauloreichert/archive/2005/05/21/1459.aspx&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3773144983876508185-6451495580163878930?l=populnet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://populnet.blogspot.com/feeds/6451495580163878930/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3773144983876508185&amp;postID=6451495580163878930' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3773144983876508185/posts/default/6451495580163878930'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3773144983876508185/posts/default/6451495580163878930'/><link rel='alternate' type='text/html' href='http://populnet.blogspot.com/2008/10/utiliser-les-custom-tools-dans-visual.html' title='Utiliser les Custom Tools dans Visual Studio'/><author><name>Popul</name><uri>http://www.blogger.com/profile/13339110117970769017</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://2.bp.blogspot.com/__831xq1hNEM/SXSGahZtTOI/AAAAAAAAAC0/YTZpJgy1wUI/S220/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/__831xq1hNEM/SOkOLGVnQVI/AAAAAAAAAAg/HxyrFplorQQ/s72-c/prop.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3773144983876508185.post-5665557979666202790</id><published>2008-05-12T13:46:00.002+02:00</published><updated>2008-10-06T11:30:30.263+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Workflow Foundation'/><title type='text'>Pourquoi développer des workflows avec Workflow Foundation ?</title><content type='html'>&lt;span xmlns=""&gt; &lt;p&gt;Tout d'abord, Workflow Foundation est un Framework permettant de réaliser des workflows tout en respectant une bonne productivité. Dorénavant, si vous pensez créer des workflows dans vos prochains projets, il est clair que vous devez penser à Workflow Foundation, surtout si vous êtes familier du Framework .Net. Si vous êtes issu du monde J2EE, PHP ou autre, il est tout à fait possible et Microsoft a travaillé dessus, de mettre en place un service quelconque, qui expose par des méthodes vos propres workflows. Tout ceci est réalisé avec un minimum d'effort si bien sûr vous disposez de Visual Studio 2005 ou 2008.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;WF propose un ensemble d'outils cohérent pour concevoir vos workflows. L'investissement requis pour comprendre WF et mettre en place un workflow est vite rentabilisé. L'éditeur de workflow fourni, permet un développement visuel et non plus textuel de vos processus. Cela se résume le plus souvent à du glisser/déplacer et à de la configuration de propriétés. Il est alors très facile à comprendre que cela augmente la maintenabilité de vos workflows.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Cet environnement graphique permet d'exposer et de discuter de vos workflows avec le client. En effet, un graphique est bien plus parlant que du texte et rien que penser à montrer du code à un client est complètement absurde. Un processus conçu visuellement avec WF est vite compréhensible par quiconque comprenant le vocabulaire métier exposé.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Lorsque vous développez vos propres workflows, vous êtes souvent amené à créer des custom activity (activités personnalisées). Ces composants ont la particularité d'être fortement réutilisables, d'une part dans un même projet mais aussi entre projets (du moment qu'ils sont indépendants). Il est tout à fait envisageable de créer une bibliothèque d'activité, que chaque développeur et architecte utilisera et alimentera.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Le Framework est fourni avec une suite d'activités standards qui couvrent un ensemble important de cas conventionnels. D'une part, ces activités vous aiguillent dans la conception de vos workflows, et d'autre part vous bénéficiez de l'expérience de Microsoft dans la matérialisation de vos processus. De plus, avec le service de persistance fourni, qui permet le stockage de vos workflows en base de données, cela a pour effet d'augmenter la fiabilité et les performances de vos applications. Le service de trace aussi fourni, permet de suivre l'exécution de vos workflows en quasi temps réel.&lt;br /&gt;&lt;/p&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3773144983876508185-5665557979666202790?l=populnet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://populnet.blogspot.com/feeds/5665557979666202790/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3773144983876508185&amp;postID=5665557979666202790' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3773144983876508185/posts/default/5665557979666202790'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3773144983876508185/posts/default/5665557979666202790'/><link rel='alternate' type='text/html' href='http://populnet.blogspot.com/2008/05/tout-dabord-workflow-foundation-est-un.html' title='Pourquoi développer des workflows avec Workflow Foundation ?'/><author><name>Popul</name><uri>http://www.blogger.com/profile/13339110117970769017</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://2.bp.blogspot.com/__831xq1hNEM/SXSGahZtTOI/AAAAAAAAAC0/YTZpJgy1wUI/S220/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3773144983876508185.post-7208698641150163473</id><published>2008-04-28T21:25:00.001+02:00</published><updated>2008-10-05T22:10:58.611+02:00</updated><title type='text'>Premier Billet !! Et surement pas le dernier :)</title><content type='html'>Et voila, j'ai enfin décidé d'ouvrir un blog pour discuter de développement, et surtout de .Net ^^.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3773144983876508185-7208698641150163473?l=populnet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://populnet.blogspot.com/feeds/7208698641150163473/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3773144983876508185&amp;postID=7208698641150163473' title='2 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3773144983876508185/posts/default/7208698641150163473'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3773144983876508185/posts/default/7208698641150163473'/><link rel='alternate' type='text/html' href='http://populnet.blogspot.com/2008/04/et-voila-jai-enfin-dcid-douvrir-un-blog.html' title='Premier Billet !! Et surement pas le dernier :)'/><author><name>Popul</name><uri>http://www.blogger.com/profile/13339110117970769017</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://2.bp.blogspot.com/__831xq1hNEM/SXSGahZtTOI/AAAAAAAAAC0/YTZpJgy1wUI/S220/photo.jpg'/></author><thr:total>2</thr:total></entry></feed>
