<?xml version="1.0" encoding="iso-8859-1"?><!-- generator="b2evolution/3.3.1" -->
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:admin="http://webns.net/mvcb/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:atom="http://www.w3.org/2005/Atom">
	<channel>
		<title>Blog de Rochdi Chakroun</title>
		<link>http://www.dotnetguru2.org/rochdichakroun/index.php</link>
		<atom:link rel="self" type="application/rss+xml" href="http://www.dotnetguru2.org/rochdichakroun/index.php?tempskin=_rss2" />
		<description></description>
		<language>en-EU</language>
		<docs>http://blogs.law.harvard.edu/tech/rss</docs>
		<admin:generatorAgent rdf:resource="http://b2evolution.net/?v=3.3.1"/>
		<ttl>60</ttl>
				<item>
			<title>DGML et Cartographie SI: Au-del&#224; de l&#8217;exploration des architectures applicatives</title>
			<link>http://www.dotnetguru2.org/rochdichakroun/index.php/2010/01/05/dgml-et-cartographie-si-au-delaagrave-de-larsquo-exploration-des-architectures-applicatives-1</link>
			<pubDate>Tue, 05 Jan 2010 09:29:41 +0000</pubDate>			<dc:creator>Rochdi Chakroun</dc:creator>
			<category domain="main">Zone Beta</category>			<guid isPermaLink="false">1186@http://www.dotnetguru2.org/</guid>
						<description>&lt;p&gt;Pour ceux qui ne le savent pas encore, Visual Studio 2010 en version Ultimate offre la possibilit&amp;#233; d'explorer et d'analyser l'architecture d'un projet. Cette fonctionnalit&amp;#233; est accessible via le menu&lt;em&gt;&lt;strong&gt; Architecture / Generate Dependency Graph. &lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;Un diagramme (&lt;strong&gt;&lt;em&gt;DGML : Directed Graph Markup Language&lt;/em&gt;&lt;/strong&gt;) repr&amp;#233;sente les composants du projet (dll, namespaces, classes) et&amp;#160; leurs relations. &lt;/p&gt;  &lt;p&gt;Si on se positionne dans un contexte entreprise, j'ai voulu utiliser le DGML pour repr&amp;#233;senter les applications au sein du SI, et ainsi profiter des outils d'analyse de Visual Studio (Circular reference, hubs .)&lt;/p&gt;  &lt;p&gt;En entr&amp;#233;e j'ai besoin d'avoir la liste des applications, les relations, le type de relation (WS, DB, File .) et en plus j'ai trouv&amp;#233; int&amp;#233;ressant de regrouper les applications par domaine (BackOffice, FrontOffice, Accounting, BI .). Ce qui va me permettre de d&amp;#233;tecter des anomalies : une application bureautique qui r&amp;#233;f&amp;#233;rence une application de production par exemple. &lt;/p&gt;  &lt;p&gt;Ci-dessous les entit&amp;#233;s Application et Relation&lt;/p&gt; &lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;  &lt;pre class=&quot;csharpcode&quot;&gt;    &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;class&lt;/span&gt; Application
    {
        &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt; Name { get;set; }
        &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt; Domain { get; set; }
    }

    &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;class&lt;/span&gt; Relation
    {
        &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt; Source { get; set; }
        &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt; Target { get; set; }
        &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt; Type { get; set; }
    }&lt;/pre&gt;

&lt;p&gt;Pour pouvoir g&amp;#233;n&amp;#233;rer du &lt;strong&gt;&lt;em&gt;DGML&lt;/em&gt;&lt;/strong&gt;, il faut r&amp;#233;f&amp;#233;rencer les DLL suivantes qui se trouvent &lt;em&gt;&lt;strong&gt;~\Program Files\visual Studio 10\Common7\Ide\PrivateAssemblies&lt;/strong&gt;&lt;/em&gt; :&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;Microsoft.VisualStudio.Progression.Common et Microsoft.VisualStudio.Progression.GraphModel&lt;/strong&gt;&lt;/em&gt; &lt;/p&gt;

&lt;p&gt;Apr&amp;#232;s avoir r&amp;#233;cup&amp;#233;rer les liste des applications, domaines, et relations il suffit de construire le graphe comme suit: &lt;/p&gt;
&lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;

&lt;pre class=&quot;csharpcode&quot;&gt;            &lt;span class=&quot;rem&quot;&gt;//Graph Creation&lt;/span&gt;
            Graph graph = &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; Graph();
            &lt;span class=&quot;rem&quot;&gt;// Create domains and add them to the graph&lt;/span&gt;
            Parallel.ForEach(domains, domain =&amp;gt;
            {
                Node node = &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; Node(domain);
                node.IsGroup = &lt;span class=&quot;kwrd&quot;&gt;true&lt;/span&gt;;
                graph.Nodes.Add(node);
            });

            &lt;span class=&quot;rem&quot;&gt;//Create application Node, and add the application to the appropriate domain&lt;/span&gt;
            Parallel.ForEach(applications, a =&amp;gt;
            {
                Node node = &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; Node(a.Name);
                graph.Nodes.Add(node);
                &lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt; domain = a.Domain;
                &lt;span class=&quot;kwrd&quot;&gt;if&lt;/span&gt; (!&lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt;.IsNullOrEmpty(domain))
                {
                    Node domainNode = graph.Nodes.FirstOrDefault(n =&amp;gt; n.Label == domain);
                    &lt;span class=&quot;kwrd&quot;&gt;if&lt;/span&gt; (domainNode != &lt;span class=&quot;kwrd&quot;&gt;null&lt;/span&gt;)
                    {
                        Link link = &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; Link(graph, domainNode, node);
                        link.SetValue(GraphProperties.IsContainment, &lt;span class=&quot;kwrd&quot;&gt;true&lt;/span&gt;);
                        graph.Links.Add(link);
                    }
                }
            });

            &lt;span class=&quot;rem&quot;&gt;//having all node, create the relations (links)&lt;/span&gt;
            Parallel.ForEach(relations, r =&amp;gt;
            {
                Link link = &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; Link(graph, graph.Nodes.First(n =&amp;gt; n.Label == r.Source), graph.Nodes.First(n =&amp;gt; n.Label == r.Target));
                link.Label = r.Type;
                graph.Links.Add(link);
            });

            &lt;span class=&quot;rem&quot;&gt;//Write the DGML to file &lt;/span&gt;
            &lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt; graphXml = graph.ToXml();

            &lt;span class=&quot;kwrd&quot;&gt;using&lt;/span&gt; (StreamWriter writer = &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; StreamWriter(&lt;span class=&quot;str&quot;&gt;&amp;quot;si.dgml&amp;quot;&lt;/span&gt;))
            {
                writer.Write(graphXml);
                writer.Flush();
            }
        }&lt;/pre&gt;

&lt;p&gt;En ouvrant le fichier dgml dans Visual Studio le r&amp;#233;sultat est le suivant : Un beau plat de spaghettis qui peut motiver l'urbanisation du SI: &lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://www.dotnetguru2.org/media/blogs/rochdichakroun/index.php/windowslivewriter/dgmletcartographiesiaudeldelexplorationd_ecb3/image_2.png&quot;&gt;&lt;img title=&quot;image&quot; style=&quot;border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px&quot; height=&quot;197&quot; alt=&quot;image&quot; src=&quot;http://www.dotnetguru2.org/media/blogs/rochdichakroun/index.php/windowslivewriter/dgmletcartographiesiaudeldelexplorationd_ecb3/image_thumb.png&quot; width=&quot;244&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;La capture d'&amp;#233;cran ci-dessous montre l'interaction d'un domaine &lt;em&gt;&lt;strong&gt;FontOffice&lt;/strong&gt;&lt;/em&gt; avec le reste du SI :&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://www.dotnetguru2.org/media/blogs/rochdichakroun/index.php/windowslivewriter/dgmletcartographiesiaudeldelexplorationd_ecb3/image_8.png&quot;&gt;&lt;img title=&quot;image&quot; style=&quot;border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px&quot; height=&quot;170&quot; alt=&quot;image&quot; src=&quot;http://www.dotnetguru2.org/media/blogs/rochdichakroun/index.php/windowslivewriter/dgmletcartographiesiaudeldelexplorationd_ecb3/image_thumb_3.png&quot; width=&quot;244&quot; border=&quot;0&quot; /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;La capture d'&amp;#233;cran ci-dessous montre l'interaction d'une application avec le reste du SI :&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://www.dotnetguru2.org/media/blogs/rochdichakroun/index.php/windowslivewriter/dgmletcartographiesiaudeldelexplorationd_ecb3/image_10.png&quot;&gt;&lt;img title=&quot;image&quot; style=&quot;border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px&quot; height=&quot;200&quot; alt=&quot;image&quot; src=&quot;http://www.dotnetguru2.org/media/blogs/rochdichakroun/index.php/windowslivewriter/dgmletcartographiesiaudeldelexplorationd_ecb3/image_thumb_4.png&quot; width=&quot;244&quot; border=&quot;0&quot; /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;La capture d'&amp;#233;cran ci-dessous montre les r&amp;#233;f&amp;#233;rences cycliques. &lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://www.dotnetguru2.org/media/blogs/rochdichakroun/index.php/windowslivewriter/dgmletcartographiesiaudeldelexplorationd_ecb3/image_12.png&quot;&gt;&lt;img title=&quot;image&quot; style=&quot;border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px&quot; height=&quot;167&quot; alt=&quot;image&quot; src=&quot;http://www.dotnetguru2.org/media/blogs/rochdichakroun/index.php/windowslivewriter/dgmletcartographiesiaudeldelexplorationd_ecb3/image_thumb_5.png&quot; width=&quot;244&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;L'outil est assez sympa bas&amp;#233; sur WPF mais malheureusement on ne peut l'utiliser qu'avec Visual Studio Ultimate et pas d'int&amp;#233;gration dans Visio.&lt;/p&gt;&lt;div class=&quot;item_footer&quot;&gt;&lt;p&gt;&lt;small&gt;&lt;a href=&quot;http://www.dotnetguru2.org/rochdichakroun/index.php/2010/01/05/dgml-et-cartographie-si-au-delaagrave-de-larsquo-exploration-des-architectures-applicatives-1&quot;&gt;Original post&lt;/a&gt; blogged on &lt;a href=&quot;http://b2evolution.net/&quot;&gt;b2evolution&lt;/a&gt;.&lt;/small&gt;&lt;/p&gt;&lt;/div&gt;</description>
			<content:encoded><![CDATA[<p>Pour ceux qui ne le savent pas encore, Visual Studio 2010 en version Ultimate offre la possibilit&#233; d'explorer et d'analyser l'architecture d'un projet. Cette fonctionnalit&#233; est accessible via le menu<em><strong> Architecture / Generate Dependency Graph. </strong></em></p>  <p>Un diagramme (<strong><em>DGML : Directed Graph Markup Language</em></strong>) repr&#233;sente les composants du projet (dll, namespaces, classes) et&#160; leurs relations. </p>  <p>Si on se positionne dans un contexte entreprise, j'ai voulu utiliser le DGML pour repr&#233;senter les applications au sein du SI, et ainsi profiter des outils d'analyse de Visual Studio (Circular reference, hubs .)</p>  <p>En entr&#233;e j'ai besoin d'avoir la liste des applications, les relations, le type de relation (WS, DB, File .) et en plus j'ai trouv&#233; int&#233;ressant de regrouper les applications par domaine (BackOffice, FrontOffice, Accounting, BI .). Ce qui va me permettre de d&#233;tecter des anomalies : une application bureautique qui r&#233;f&#233;rence une application de production par exemple. </p>  <p>Ci-dessous les entit&#233;s Application et Relation</p> <!-- code formatted by http://manoli.net/csharpformat/ -->  <pre class="csharpcode">    <span class="kwrd">public</span> <span class="kwrd">class</span> Application
    {
        <span class="kwrd">public</span> <span class="kwrd">string</span> Name { get;set; }
        <span class="kwrd">public</span> <span class="kwrd">string</span> Domain { get; set; }
    }

    <span class="kwrd">public</span> <span class="kwrd">class</span> Relation
    {
        <span class="kwrd">public</span> <span class="kwrd">string</span> Source { get; set; }
        <span class="kwrd">public</span> <span class="kwrd">string</span> Target { get; set; }
        <span class="kwrd">public</span> <span class="kwrd">string</span> Type { get; set; }
    }</pre>

<p>Pour pouvoir g&#233;n&#233;rer du <strong><em>DGML</em></strong>, il faut r&#233;f&#233;rencer les DLL suivantes qui se trouvent <em><strong>~\Program Files\visual Studio 10\Common7\Ide\PrivateAssemblies</strong></em> :</p>

<p><em><strong>Microsoft.VisualStudio.Progression.Common et Microsoft.VisualStudio.Progression.GraphModel</strong></em> </p>

<p>Apr&#232;s avoir r&#233;cup&#233;rer les liste des applications, domaines, et relations il suffit de construire le graphe comme suit: </p>
<!-- code formatted by http://manoli.net/csharpformat/ -->

<pre class="csharpcode">            <span class="rem">//Graph Creation</span>
            Graph graph = <span class="kwrd">new</span> Graph();
            <span class="rem">// Create domains and add them to the graph</span>
            Parallel.ForEach(domains, domain =&gt;
            {
                Node node = <span class="kwrd">new</span> Node(domain);
                node.IsGroup = <span class="kwrd">true</span>;
                graph.Nodes.Add(node);
            });

            <span class="rem">//Create application Node, and add the application to the appropriate domain</span>
            Parallel.ForEach(applications, a =&gt;
            {
                Node node = <span class="kwrd">new</span> Node(a.Name);
                graph.Nodes.Add(node);
                <span class="kwrd">string</span> domain = a.Domain;
                <span class="kwrd">if</span> (!<span class="kwrd">string</span>.IsNullOrEmpty(domain))
                {
                    Node domainNode = graph.Nodes.FirstOrDefault(n =&gt; n.Label == domain);
                    <span class="kwrd">if</span> (domainNode != <span class="kwrd">null</span>)
                    {
                        Link link = <span class="kwrd">new</span> Link(graph, domainNode, node);
                        link.SetValue(GraphProperties.IsContainment, <span class="kwrd">true</span>);
                        graph.Links.Add(link);
                    }
                }
            });

            <span class="rem">//having all node, create the relations (links)</span>
            Parallel.ForEach(relations, r =&gt;
            {
                Link link = <span class="kwrd">new</span> Link(graph, graph.Nodes.First(n =&gt; n.Label == r.Source), graph.Nodes.First(n =&gt; n.Label == r.Target));
                link.Label = r.Type;
                graph.Links.Add(link);
            });

            <span class="rem">//Write the DGML to file </span>
            <span class="kwrd">string</span> graphXml = graph.ToXml();

            <span class="kwrd">using</span> (StreamWriter writer = <span class="kwrd">new</span> StreamWriter(<span class="str">&quot;si.dgml&quot;</span>))
            {
                writer.Write(graphXml);
                writer.Flush();
            }
        }</pre>

<p>En ouvrant le fichier dgml dans Visual Studio le r&#233;sultat est le suivant : Un beau plat de spaghettis qui peut motiver l'urbanisation du SI: </p>

<p><a href="http://www.dotnetguru2.org/media/blogs/rochdichakroun/index.php/windowslivewriter/dgmletcartographiesiaudeldelexplorationd_ecb3/image_2.png"><img title="image" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="197" alt="image" src="http://www.dotnetguru2.org/media/blogs/rochdichakroun/index.php/windowslivewriter/dgmletcartographiesiaudeldelexplorationd_ecb3/image_thumb.png" width="244" border="0" /></a></p>

<p>La capture d'&#233;cran ci-dessous montre l'interaction d'un domaine <em><strong>FontOffice</strong></em> avec le reste du SI :</p>

<p><a href="http://www.dotnetguru2.org/media/blogs/rochdichakroun/index.php/windowslivewriter/dgmletcartographiesiaudeldelexplorationd_ecb3/image_8.png"><img title="image" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="170" alt="image" src="http://www.dotnetguru2.org/media/blogs/rochdichakroun/index.php/windowslivewriter/dgmletcartographiesiaudeldelexplorationd_ecb3/image_thumb_3.png" width="244" border="0" /></a> </p>

<p>La capture d'&#233;cran ci-dessous montre l'interaction d'une application avec le reste du SI :</p>

<p><a href="http://www.dotnetguru2.org/media/blogs/rochdichakroun/index.php/windowslivewriter/dgmletcartographiesiaudeldelexplorationd_ecb3/image_10.png"><img title="image" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="200" alt="image" src="http://www.dotnetguru2.org/media/blogs/rochdichakroun/index.php/windowslivewriter/dgmletcartographiesiaudeldelexplorationd_ecb3/image_thumb_4.png" width="244" border="0" /></a> </p>

<p>La capture d'&#233;cran ci-dessous montre les r&#233;f&#233;rences cycliques. </p>

<p><a href="http://www.dotnetguru2.org/media/blogs/rochdichakroun/index.php/windowslivewriter/dgmletcartographiesiaudeldelexplorationd_ecb3/image_12.png"><img title="image" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="167" alt="image" src="http://www.dotnetguru2.org/media/blogs/rochdichakroun/index.php/windowslivewriter/dgmletcartographiesiaudeldelexplorationd_ecb3/image_thumb_5.png" width="244" border="0" /></a></p>

<p>L'outil est assez sympa bas&#233; sur WPF mais malheureusement on ne peut l'utiliser qu'avec Visual Studio Ultimate et pas d'int&#233;gration dans Visio.</p><div class="item_footer"><p><small><a href="http://www.dotnetguru2.org/rochdichakroun/index.php/2010/01/05/dgml-et-cartographie-si-au-delaagrave-de-larsquo-exploration-des-architectures-applicatives-1">Original post</a> blogged on <a href="http://b2evolution.net/">b2evolution</a>.</small></p></div>]]></content:encoded>
								<comments>http://www.dotnetguru2.org/rochdichakroun/index.php/2010/01/05/dgml-et-cartographie-si-au-delaagrave-de-larsquo-exploration-des-architectures-applicatives-1#comments</comments>
			<wfw:commentRss>http://www.dotnetguru2.org/rochdichakroun/index.php?tempskin=_rss2&#38;disp=comments&#38;p=1186</wfw:commentRss>
		</item>
				<item>
			<title>[Concours MS] Gagner une Table surface</title>
			<link>http://www.dotnetguru2.org/rochdichakroun/index.php/2009/07/21/concours_ms_gagner_une_table_surface</link>
			<pubDate>Tue, 21 Jul 2009 10:23:46 +0000</pubDate>			<dc:creator>Rochdi Chakroun</dc:creator>
			<category domain="main">.NET Balabala</category>			<guid isPermaLink="false">1095@http://www.dotnetguru2.org/</guid>
						<description>&lt;p&gt;Pour ceux qui veulent embellir leur salon avec une table surface (pas comme &lt;a href=&quot;http://blogs.developpeur.org/azra/archive/2009/06/05/hors-sujet-je-viens-de-recevoir-ma-table-surface.aspx&quot;&gt;celle de Florent Santin&lt;/a&gt;). Microsoft lance un concours pour ses partenaires autour de la table surface.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://partner.surface.com/EN/Pages/OfficialRules.aspx&quot;&gt;R&amp;#232;glements&lt;/a&gt;  &lt;/p&gt;&lt;div class=&quot;item_footer&quot;&gt;&lt;p&gt;&lt;small&gt;&lt;a href=&quot;http://www.dotnetguru2.org/rochdichakroun/index.php/2009/07/21/concours_ms_gagner_une_table_surface&quot;&gt;Original post&lt;/a&gt; blogged on &lt;a href=&quot;http://b2evolution.net/&quot;&gt;b2evolution&lt;/a&gt;.&lt;/small&gt;&lt;/p&gt;&lt;/div&gt;</description>
			<content:encoded><![CDATA[<p>Pour ceux qui veulent embellir leur salon avec une table surface (pas comme <a href="http://blogs.developpeur.org/azra/archive/2009/06/05/hors-sujet-je-viens-de-recevoir-ma-table-surface.aspx">celle de Florent Santin</a>). Microsoft lance un concours pour ses partenaires autour de la table surface.</p>

<p><a href="http://partner.surface.com/EN/Pages/OfficialRules.aspx">R&#232;glements</a>  </p><div class="item_footer"><p><small><a href="http://www.dotnetguru2.org/rochdichakroun/index.php/2009/07/21/concours_ms_gagner_une_table_surface">Original post</a> blogged on <a href="http://b2evolution.net/">b2evolution</a>.</small></p></div>]]></content:encoded>
								<comments>http://www.dotnetguru2.org/rochdichakroun/index.php/2009/07/21/concours_ms_gagner_une_table_surface#comments</comments>
			<wfw:commentRss>http://www.dotnetguru2.org/rochdichakroun/index.php?tempskin=_rss2&#38;disp=comments&#38;p=1095</wfw:commentRss>
		</item>
				<item>
			<title>The code name Geneva is no more &#8230;</title>
			<link>http://www.dotnetguru2.org/rochdichakroun/index.php/2009/07/15/the_code_name_geneva_is_no_more</link>
			<pubDate>Wed, 15 Jul 2009 12:58:04 +0000</pubDate>			<dc:creator>Rochdi Chakroun</dc:creator>
			<category domain="main">.NET Balabala</category>			<guid isPermaLink="false">1091@http://www.dotnetguru2.org/</guid>
						<description>&lt;p&gt;Le nom de code &amp;#8220;Geneva &amp;#8221; qui regroupe les produits suivant: Geneva Server, Geneva Framework et Windows Cardspace Geneva va &amp;#234;tre remplac&amp;#233; par le nom officiel des produits:&lt;br /&gt;
 &lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;Geneva Server passe en Active Directory Federation Services : ADFS (pas de surprise)&lt;/li&gt;

	&lt;li&gt;Geneva Framework passe en Windows Identity Foundation (WIF :  Pas mal)&lt;/li&gt;

	&lt;li&gt;Windows Cardspace Geneva passe en windows cardspace (pas de surprise)&lt;/li&gt;

&lt;/ul&gt;

&lt;div class=&quot;item_footer&quot;&gt;&lt;p&gt;&lt;small&gt;&lt;a href=&quot;http://www.dotnetguru2.org/rochdichakroun/index.php/2009/07/15/the_code_name_geneva_is_no_more&quot;&gt;Original post&lt;/a&gt; blogged on &lt;a href=&quot;http://b2evolution.net/&quot;&gt;b2evolution&lt;/a&gt;.&lt;/small&gt;&lt;/p&gt;&lt;/div&gt;</description>
			<content:encoded><![CDATA[<p>Le nom de code &#8220;Geneva &#8221; qui regroupe les produits suivant: Geneva Server, Geneva Framework et Windows Cardspace Geneva va &#234;tre remplac&#233; par le nom officiel des produits:<br />
 </p>
<ul>
	<li>Geneva Server passe en Active Directory Federation Services : ADFS (pas de surprise)</li>

	<li>Geneva Framework passe en Windows Identity Foundation (WIF :  Pas mal)</li>

	<li>Windows Cardspace Geneva passe en windows cardspace (pas de surprise)</li>

</ul>

<div class="item_footer"><p><small><a href="http://www.dotnetguru2.org/rochdichakroun/index.php/2009/07/15/the_code_name_geneva_is_no_more">Original post</a> blogged on <a href="http://b2evolution.net/">b2evolution</a>.</small></p></div>]]></content:encoded>
								<comments>http://www.dotnetguru2.org/rochdichakroun/index.php/2009/07/15/the_code_name_geneva_is_no_more#comments</comments>
			<wfw:commentRss>http://www.dotnetguru2.org/rochdichakroun/index.php?tempskin=_rss2&#38;disp=comments&#38;p=1091</wfw:commentRss>
		</item>
				<item>
			<title>Sun Cloud limit&#233; aux employ&#233;s de Sun </title>
			<link>http://www.dotnetguru2.org/rochdichakroun/index.php/2009/07/08/sun_cloud_limite_aux_employes_de_sun</link>
			<pubDate>Wed, 08 Jul 2009 09:39:45 +0000</pubDate>			<dc:creator>Rochdi Chakroun</dc:creator>
			<category domain="main">.NET Balabala</category>			<guid isPermaLink="false">1086@http://www.dotnetguru2.org/</guid>
						<description>&lt;p&gt;Je me suis &lt;a href=&quot;https://www2.sun.de/dct/forms/reg_us_2409_516_0.jsp&quot;&gt;inscrit &lt;/a&gt; y a deux semaines pour avoir un early access au &lt;a href=&quot;http://www.sun.com/solutions/cloudcomputing/index.jsp&quot;&gt;sun cloud &lt;/a&gt;et toujours  pas d&amp;#8217;access code. J&amp;#8217;ai demand&amp;#233; donc des informations au support et la r&amp;#233;ponse est assez claire : &lt;/p&gt;

&lt;p&gt;&lt;em&gt;The Sun Cloud is not currently available for external use.  The sign up form you filled out gets you onto the early access list, and once we're ready to open the service for early access, you will receive information on how to access the service.  But at this time, the service only is available internally to Sun employees.&lt;/em&gt;&lt;/p&gt;&lt;div class=&quot;item_footer&quot;&gt;&lt;p&gt;&lt;small&gt;&lt;a href=&quot;http://www.dotnetguru2.org/rochdichakroun/index.php/2009/07/08/sun_cloud_limite_aux_employes_de_sun&quot;&gt;Original post&lt;/a&gt; blogged on &lt;a href=&quot;http://b2evolution.net/&quot;&gt;b2evolution&lt;/a&gt;.&lt;/small&gt;&lt;/p&gt;&lt;/div&gt;</description>
			<content:encoded><![CDATA[<p>Je me suis <a href="https://www2.sun.de/dct/forms/reg_us_2409_516_0.jsp">inscrit </a> y a deux semaines pour avoir un early access au <a href="http://www.sun.com/solutions/cloudcomputing/index.jsp">sun cloud </a>et toujours  pas d&#8217;access code. J&#8217;ai demand&#233; donc des informations au support et la r&#233;ponse est assez claire : </p>

<p><em>The Sun Cloud is not currently available for external use.  The sign up form you filled out gets you onto the early access list, and once we're ready to open the service for early access, you will receive information on how to access the service.  But at this time, the service only is available internally to Sun employees.</em></p><div class="item_footer"><p><small><a href="http://www.dotnetguru2.org/rochdichakroun/index.php/2009/07/08/sun_cloud_limite_aux_employes_de_sun">Original post</a> blogged on <a href="http://b2evolution.net/">b2evolution</a>.</small></p></div>]]></content:encoded>
								<comments>http://www.dotnetguru2.org/rochdichakroun/index.php/2009/07/08/sun_cloud_limite_aux_employes_de_sun#comments</comments>
			<wfw:commentRss>http://www.dotnetguru2.org/rochdichakroun/index.php?tempskin=_rss2&#38;disp=comments&#38;p=1086</wfw:commentRss>
		</item>
				<item>
			<title>Re: L&#8217;objet, c&#8217;est beau</title>
			<link>http://www.dotnetguru2.org/rochdichakroun/index.php/2009/06/30/re_l_objet_c_est_beau</link>
			<pubDate>Tue, 30 Jun 2009 13:56:22 +0000</pubDate>			<dc:creator>Rochdi Chakroun</dc:creator>
			<category domain="main">.NET Balabala</category>			<guid isPermaLink="false">1084@http://www.dotnetguru2.org/</guid>
						<description>&lt;p&gt;&lt;a href=&quot;http://blogs.developpeur.org/matthieu/default.aspx&quot;&gt;Matthieu Mezil&lt;/a&gt;, artiste de l&amp;#8217;objet,  est parti pour son article &lt;a href=&quot;http://www.techheadbrothers.com/Articles.aspx/objet-beau&quot;&gt;L&amp;#8217;objet, c&amp;#8217;est beau&lt;/a&gt;  du besoin suivant:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;Prendre un fichier en entr&amp;#233;e, effectuer un traitement sur celui-ci puis sauvegarder les modifications dans un fichier de sortie.&lt;/li&gt;
	&lt;li&gt;Par d&amp;#233;faut, il propose deux types de traitements : l&amp;#8217;inversion des caract&amp;#232;res ligne par ligne et la num&amp;#233;rotation des lignes.&lt;/li&gt;
	&lt;li&gt;De plus, il veut que les traitements soient composables &amp;#224; l&amp;#8217;infini et qu&amp;#8217;ils puissent &amp;#234;tre utilis&amp;#233;s ind&amp;#233;pendant de la notion de fichiers.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;L&amp;#8217;article traite plusieurs probl&amp;#233;matiques comme le threading, la gestion d&amp;#8217;erreurs &amp;#8230; Je vais m&amp;#8217;int&amp;#233;resser juste &amp;#224; la premi&amp;#232;re partie : l&amp;#8217;acte de cr&amp;#233;ation du &amp;#171; chef-d&amp;#8217;&amp;#339;uvre &amp;#187;. &lt;/p&gt;

&lt;p&gt;L&amp;#8217;artiste  propose d&amp;#8217;organiser sa solution en 2 couches UI et Business, d&amp;#233;j&amp;#224; ce choix artistique me pose probl&amp;#232;me &amp;#8230; pourquoi deux couches ? Pourquoi pas une seule ? Pourquoi pas 5 ? &lt;br /&gt;
Enfaite on conna&amp;#238;t tous la r&amp;#233;ponse, mais on a tendance &amp;#224; concevoir nos applications en n-couche par habitude / respect des bonnes pratiques. Ce reflexe acquis (chez d&amp;#8217;autres d&amp;#233;veloppeurs c&amp;#8217;est m&amp;#234;me un reflexe inn&amp;#233;) peut parfois nuire &amp;#224; la sant&amp;#233; de la solution. &lt;/p&gt;

&lt;p&gt;Dans notre cas, la probl&amp;#233;matique pos&amp;#233;e est assez simple par rapport &amp;#224; la complexit&amp;#233; des projets r&amp;#233;els, le choix de plusieurs couches dans cet exemple n&amp;#8217;est d&amp;#251; aux contrainte de maintanabilit&amp;#233; / scalabilit&amp;#233; / extensibilit&amp;#233; &amp;#8230; Mais probablement pour consolider la structure de la solution : J&amp;#8217;aurai pr&amp;#233;f&amp;#233;r&amp;#233; si Matthieu partait d&amp;#8217;une seule couche, un seul centre fort qui encapsule plusieurs sous-centres (centres latents + centres faibles) : UI / interface avec l&amp;#8217;infra (manipulation des fichiers) / Traitement des donn&amp;#233;es )  et qu&amp;#8217;en avan&amp;#231;ant dans son analyse il faisait &amp;#233;voluer sa solution en passant  les centres latents en centre forts et en &amp;#233;liminant les centres faibles &amp;#8230; Par exemple l&amp;#8217;application au d&amp;#233;but se limite &amp;#224; une application client lourd et petite &amp;#224; petit un nouveau centre celui du traitement appara&amp;#238;t et on l&amp;#8217;externalise dans une couche &amp;#224; part.&lt;br /&gt;
 &lt;br /&gt;
De nos deux couche business / UI Matthieu a fait un zoom X 1000, et on se retrouve en train de discuter d&amp;#8217;une interface IStringsTransform ! Moi, j&amp;#8217;ai eu le vertige&amp;#8230; On est pass&amp;#233; d&amp;#8217;un level of scale de l&amp;#8217;ordre de l&amp;#8217;assembly &amp;#224; celui d&amp;#8217;une interface ! comme si un architecte te pr&amp;#233;sente la structure des &amp;#233;tages de ta futur maison et juste apr&amp;#232;s il enchaine avec l&amp;#8217;emplacement du divan dans ton salon. &lt;br /&gt;
Autre soucis avec le Zooming, l&amp;#8217;artiste fait r&amp;#233;f&amp;#233;rence aux designs patterns. Les design patterns c&amp;#8217;est bien mais se focalisent sur une partie du syst&amp;#232;me: Avec un zoom r&amp;#233;gl&amp;#233; au niveau objet, on risque donc de perdre de vue la solution globale.&lt;/p&gt;

&lt;p&gt;Ce que j&amp;#8217;aurai aim&amp;#233; trouver dans l&amp;#8217;article, c&amp;#8217;est une explication plus d&amp;#233;taill&amp;#233; de l&amp;#8217;approche, une analogie avec le monde r&amp;#233;el peut &amp;#234;tre. &lt;br /&gt;
Dans notre cas, on a un fichier et des transformations  qu&amp;#8217;on peut composer s&amp;#233;quentiellement. Ca ressemble &amp;#224; mettre une capsule Nespresso dans la machine, demander une transformation (caf&amp;#233; court / moyen / et long) en appuyant sur la commande ad&amp;#233;quate :crazy:. On a donc des commandes qui r&amp;#233;f&amp;#233;rencent  les transformations et un invoker a qui  l&amp;#8217;utilisateur associe &amp;#224; la demande une commande, la commande &amp;#224; son tour va s&amp;#8217;appuyer sur la transformation pour satisfaire la requ&amp;#234;te du client:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://www.dotnetguru2.org/media/ClassDiagram_01.png&quot; border=&quot;0&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Pour l'utilisation:&lt;/p&gt;

&lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;
&lt;p&gt;&lt;style type=&quot;text/css&quot;&gt;&lt;br /&gt;
.csharpcode, .csharpcode pre&lt;br /&gt;
{&lt;br /&gt;
	font-size: small;&lt;br /&gt;
	color: black;&lt;br /&gt;
	font-family: Consolas, &quot;Courier New&quot;, Courier, Monospace;&lt;br /&gt;
	background-color: #ffffff;&lt;br /&gt;
	/*white-space: pre;*/&lt;br /&gt;
}&lt;/p&gt;

&lt;p&gt;.csharpcode pre { margin: 0em; }&lt;/p&gt;

&lt;p&gt;.csharpcode .rem { color: #008000; }&lt;/p&gt;

&lt;p&gt;.csharpcode .kwrd { color: #0000ff; }&lt;/p&gt;

&lt;p&gt;.csharpcode .str { color: #006080; }&lt;/p&gt;

&lt;p&gt;.csharpcode .op { color: #0000c0; }&lt;/p&gt;

&lt;p&gt;.csharpcode .preproc { color: #cc6633; }&lt;/p&gt;

&lt;p&gt;.csharpcode .asp { background-color: #ffff00; }&lt;/p&gt;

&lt;p&gt;.csharpcode .html { color: #800000; }&lt;/p&gt;

&lt;p&gt;.csharpcode .attr { color: #ff0000; }&lt;/p&gt;

&lt;p&gt;.csharpcode .alt &lt;br /&gt;
{&lt;br /&gt;
	background-color: #f4f4f4;&lt;br /&gt;
	width: 100%;&lt;br /&gt;
	margin: 0em;&lt;br /&gt;
}&lt;/p&gt;

.csharpcode .lnum { color: #606060; }&lt;br /&gt;
&lt;/style&gt;
&lt;p&gt;&lt;/p&gt;&lt;pre class=&quot;csharpcode&quot;&gt;
            ILineTransformation lineNumberTransformation = &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; LineNumberTransformation();
            TransformCommand lineNumberTransformCommand = &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; TransformCommand(lineNumberTransformation);
            ILineTransformation reverseCharLineTransformation = &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; ReverseCharLineTransformation();
            TransformCommand reverseTransformCommand = &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; TransformCommand(reverseCharLineTransformation);
            TransformationRemote remote = &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; TransformationRemote();
            remote.CurrentCommand = reverseTransformCommand;
            var resultWithReverse = remote.Zapping(input);
            remote.CurrentCommand = lineNumberTransformCommand;
            var resultWithLineNumber = remote.Zapping(input);&lt;/pre&gt;


    
&lt;div class=&quot;item_footer&quot;&gt;&lt;p&gt;&lt;small&gt;&lt;a href=&quot;http://www.dotnetguru2.org/rochdichakroun/index.php/2009/06/30/re_l_objet_c_est_beau&quot;&gt;Original post&lt;/a&gt; blogged on &lt;a href=&quot;http://b2evolution.net/&quot;&gt;b2evolution&lt;/a&gt;.&lt;/small&gt;&lt;/p&gt;&lt;/div&gt;</description>
			<content:encoded><![CDATA[<p><a href="http://blogs.developpeur.org/matthieu/default.aspx">Matthieu Mezil</a>, artiste de l&#8217;objet,  est parti pour son article <a href="http://www.techheadbrothers.com/Articles.aspx/objet-beau">L&#8217;objet, c&#8217;est beau</a>  du besoin suivant:</p>
<ul>
	<li>Prendre un fichier en entr&#233;e, effectuer un traitement sur celui-ci puis sauvegarder les modifications dans un fichier de sortie.</li>
	<li>Par d&#233;faut, il propose deux types de traitements : l&#8217;inversion des caract&#232;res ligne par ligne et la num&#233;rotation des lignes.</li>
	<li>De plus, il veut que les traitements soient composables &#224; l&#8217;infini et qu&#8217;ils puissent &#234;tre utilis&#233;s ind&#233;pendant de la notion de fichiers.</li>
</ul>

<p>L&#8217;article traite plusieurs probl&#233;matiques comme le threading, la gestion d&#8217;erreurs &#8230; Je vais m&#8217;int&#233;resser juste &#224; la premi&#232;re partie : l&#8217;acte de cr&#233;ation du &#171; chef-d&#8217;&#339;uvre &#187;. </p>

<p>L&#8217;artiste  propose d&#8217;organiser sa solution en 2 couches UI et Business, d&#233;j&#224; ce choix artistique me pose probl&#232;me &#8230; pourquoi deux couches ? Pourquoi pas une seule ? Pourquoi pas 5 ? <br />
Enfaite on conna&#238;t tous la r&#233;ponse, mais on a tendance &#224; concevoir nos applications en n-couche par habitude / respect des bonnes pratiques. Ce reflexe acquis (chez d&#8217;autres d&#233;veloppeurs c&#8217;est m&#234;me un reflexe inn&#233;) peut parfois nuire &#224; la sant&#233; de la solution. </p>

<p>Dans notre cas, la probl&#233;matique pos&#233;e est assez simple par rapport &#224; la complexit&#233; des projets r&#233;els, le choix de plusieurs couches dans cet exemple n&#8217;est d&#251; aux contrainte de maintanabilit&#233; / scalabilit&#233; / extensibilit&#233; &#8230; Mais probablement pour consolider la structure de la solution : J&#8217;aurai pr&#233;f&#233;r&#233; si Matthieu partait d&#8217;une seule couche, un seul centre fort qui encapsule plusieurs sous-centres (centres latents + centres faibles) : UI / interface avec l&#8217;infra (manipulation des fichiers) / Traitement des donn&#233;es )  et qu&#8217;en avan&#231;ant dans son analyse il faisait &#233;voluer sa solution en passant  les centres latents en centre forts et en &#233;liminant les centres faibles &#8230; Par exemple l&#8217;application au d&#233;but se limite &#224; une application client lourd et petite &#224; petit un nouveau centre celui du traitement appara&#238;t et on l&#8217;externalise dans une couche &#224; part.<br />
 <br />
De nos deux couche business / UI Matthieu a fait un zoom X 1000, et on se retrouve en train de discuter d&#8217;une interface IStringsTransform ! Moi, j&#8217;ai eu le vertige&#8230; On est pass&#233; d&#8217;un level of scale de l&#8217;ordre de l&#8217;assembly &#224; celui d&#8217;une interface ! comme si un architecte te pr&#233;sente la structure des &#233;tages de ta futur maison et juste apr&#232;s il enchaine avec l&#8217;emplacement du divan dans ton salon. <br />
Autre soucis avec le Zooming, l&#8217;artiste fait r&#233;f&#233;rence aux designs patterns. Les design patterns c&#8217;est bien mais se focalisent sur une partie du syst&#232;me: Avec un zoom r&#233;gl&#233; au niveau objet, on risque donc de perdre de vue la solution globale.</p>

<p>Ce que j&#8217;aurai aim&#233; trouver dans l&#8217;article, c&#8217;est une explication plus d&#233;taill&#233; de l&#8217;approche, une analogie avec le monde r&#233;el peut &#234;tre. <br />
Dans notre cas, on a un fichier et des transformations  qu&#8217;on peut composer s&#233;quentiellement. Ca ressemble &#224; mettre une capsule Nespresso dans la machine, demander une transformation (caf&#233; court / moyen / et long) en appuyant sur la commande ad&#233;quate :crazy:. On a donc des commandes qui r&#233;f&#233;rencent  les transformations et un invoker a qui  l&#8217;utilisateur associe &#224; la demande une commande, la commande &#224; son tour va s&#8217;appuyer sur la transformation pour satisfaire la requ&#234;te du client:</p>

<p><img src="http://www.dotnetguru2.org/media/ClassDiagram_01.png" border="0" alt="" /></p>

<p>Pour l'utilisation:</p>

<!-- code formatted by http://manoli.net/csharpformat/ -->
<p><style type="text/css"><br />
.csharpcode, .csharpcode pre<br />
{<br />
	font-size: small;<br />
	color: black;<br />
	font-family: Consolas, "Courier New", Courier, Monospace;<br />
	background-color: #ffffff;<br />
	/*white-space: pre;*/<br />
}</p>

<p>.csharpcode pre { margin: 0em; }</p>

<p>.csharpcode .rem { color: #008000; }</p>

<p>.csharpcode .kwrd { color: #0000ff; }</p>

<p>.csharpcode .str { color: #006080; }</p>

<p>.csharpcode .op { color: #0000c0; }</p>

<p>.csharpcode .preproc { color: #cc6633; }</p>

<p>.csharpcode .asp { background-color: #ffff00; }</p>

<p>.csharpcode .html { color: #800000; }</p>

<p>.csharpcode .attr { color: #ff0000; }</p>

<p>.csharpcode .alt <br />
{<br />
	background-color: #f4f4f4;<br />
	width: 100%;<br />
	margin: 0em;<br />
}</p>

.csharpcode .lnum { color: #606060; }<br />
</style>
<p></p><pre class="csharpcode">
            ILineTransformation lineNumberTransformation = <span class="kwrd">new</span> LineNumberTransformation();
            TransformCommand lineNumberTransformCommand = <span class="kwrd">new</span> TransformCommand(lineNumberTransformation);
            ILineTransformation reverseCharLineTransformation = <span class="kwrd">new</span> ReverseCharLineTransformation();
            TransformCommand reverseTransformCommand = <span class="kwrd">new</span> TransformCommand(reverseCharLineTransformation);
            TransformationRemote remote = <span class="kwrd">new</span> TransformationRemote();
            remote.CurrentCommand = reverseTransformCommand;
            var resultWithReverse = remote.Zapping(input);
            remote.CurrentCommand = lineNumberTransformCommand;
            var resultWithLineNumber = remote.Zapping(input);</pre>


    
<div class="item_footer"><p><small><a href="http://www.dotnetguru2.org/rochdichakroun/index.php/2009/06/30/re_l_objet_c_est_beau">Original post</a> blogged on <a href="http://b2evolution.net/">b2evolution</a>.</small></p></div>]]></content:encoded>
								<comments>http://www.dotnetguru2.org/rochdichakroun/index.php/2009/06/30/re_l_objet_c_est_beau#comments</comments>
			<wfw:commentRss>http://www.dotnetguru2.org/rochdichakroun/index.php?tempskin=_rss2&#38;disp=comments&#38;p=1084</wfw:commentRss>
		</item>
				<item>
			<title>ALT.NET : Adaptative Object Model et DDD</title>
			<link>http://www.dotnetguru2.org/rochdichakroun/index.php/2009/05/20/alt_net_adaptative_object_model_et_ddd</link>
			<pubDate>Wed, 20 May 2009 14:24:27 +0000</pubDate>			<dc:creator>Rochdi Chakroun</dc:creator>
			<category domain="main">Architecture</category>			<guid isPermaLink="false">1061@http://www.dotnetguru2.org/</guid>
						<description>&lt;p&gt;Dans l&amp;#8217;approche Domain Driven Design, le c&amp;#339;ur de la solution c&amp;#8217;est le domaine m&amp;#233;tier. Du point technique le domaine est en g&amp;#233;n&amp;#233;ral une assembly centrale qui est r&amp;#233;f&amp;#233;renc&amp;#233;e par toutes les couches qui gravitent autour du domaine (repository, service, infra, UI, tests unitaires et fonctionnels). Cette d&amp;#233;pendance forte est souvent montr&amp;#233;e du doigt par certains coll&amp;#232;gues pro active record et qui pensent que les donn&amp;#233;es c&amp;#8217;est 90% du business.  Et la question qui pose est : &quot;Souvent&quot; le client  est amen&amp;#233; &amp;#224; faire &amp;#233;voluer ses process et &amp;#224; mettre &amp;#224; jour son m&amp;#233;tier, dans ce cas il faut refaire toute l&amp;#8217;application &amp;#224; cause de cette d&amp;#233;pendance. En g&amp;#233;n&amp;#233;ral je r&amp;#233;ponds que normalement le client change rarement de processus et que le c&amp;#339;ur du m&amp;#233;tier est toujours le m&amp;#234;me, donc l&amp;#8217;&amp;#233;volution &amp;#224; apporter dans le mod&amp;#232;le n&amp;#8217;est pas importante, et en g&amp;#233;n&amp;#233;ral c&amp;#8217;est l&amp;#8217;infrastructure qui change (base de donn&amp;#233;es, fichiers, Service web &amp;#8230; ) et ca on sait g&amp;#233;rer, si l&amp;#8217;impl&amp;#233;mentation des infras sont facilement injectables. Mais admettant que le client revoit ses process et son c&amp;#339;ur de m&amp;#233;tier tout les mois &amp;#8230; que faire ? Je suis all&amp;#233; chercher une r&amp;#233;ponse hier dans la pr&amp;#233;sentation anim&amp;#233;e par Sebastien Ros au sujet de l&amp;#8217;Adaptative Object Model. Et je me suis rendu compte que faire du &amp;#171; DDD adaptable &amp;#187; c&amp;#8217;&amp;#233;tait faisable : En DDD on manipule des entit&amp;#233;s qui ont des propri&amp;#233;t&amp;#233;s, des relations avec d&amp;#8217;autres entit&amp;#233;s, des value type, et contient des comportements  qui encapsule la logique m&amp;#233;tier. Il suffit donc de faire une m&amp;#233;ta description des &amp;#233;l&amp;#233;ments de base pour monter et manipuler un domaine : un customer par exemple est une instance de meta type entit&amp;#233; qui a les propri&amp;#233;t&amp;#233;s suivantes : FirstName, LastName, Address, et une liste de commande. Son comportement se r&amp;#233;sume ainsi : s&amp;#8217;il a d&amp;#233;j&amp;#224; d&amp;#233;pens&amp;#233; 500 euros, il a droit &amp;#224; 10% de remise sur sa prochaine commande. Au-del&amp;#224; des objets du domaine, on peut aussi automatiser la cr&amp;#233;ation des repositories si une entit&amp;#233; est marqu&amp;#233;e par l&amp;#8217;attribut &amp;#171; root  agregate &amp;#187; &amp;#8230; &lt;br /&gt;
Imaginons que c&amp;#8217;est faisable, et imaginons qu&amp;#8217;une soci&amp;#233;t&amp;#233; A a rachet&amp;#233; une soci&amp;#233;t&amp;#233; B, et imaginons que soci&amp;#233;t&amp;#233; A et B on d&amp;#233;j&amp;#224; des domaines adaptables (utilisation de l&amp;#8217;AOM dans une optique DDD). La mise en relation des syst&amp;#232;mes d&amp;#8217;information devient simple car il suffit de s&amp;#8217;&amp;#233;changer les m&amp;#233;ta-descriptions respectives de leurs domaines et enfin  d&amp;#8217;appliquer des r&amp;#232;gles de transformation. Par exemple :&lt;br /&gt;
Pour la soci&amp;#233;t&amp;#233; A, un customer poss&amp;#232;de les propri&amp;#233;t&amp;#233;s : AddressLine, ZipCode, Country et pour la soci&amp;#233;t&amp;#233; B un Customer a la propri&amp;#233;t&amp;#233; Address. La r&amp;#232;gle &amp;#224; introduire c&amp;#244;t&amp;#233; soci&amp;#233;t&amp;#233; B est : Address = AddressLine +  ZipCode + Country. Toutes ces r&amp;#232;gles sont au niveau des m&amp;#233;ta-descriptions et sont facilement &amp;#233;changeable : Ficher XML par exemple. Mieux encore, si l&amp;#8217;on met en place un monitoring des fichiers de m&amp;#233;ta-description on peut automatiquement mettre &amp;#224; jour les r&amp;#232;gles d&amp;#8217;adaptation  au sein des soci&amp;#233;t&amp;#233;s s&amp;#8217;interfa&amp;#231;ant avec le syst&amp;#232;me.  &lt;/p&gt;
&lt;div class=&quot;item_footer&quot;&gt;&lt;p&gt;&lt;small&gt;&lt;a href=&quot;http://www.dotnetguru2.org/rochdichakroun/index.php/2009/05/20/alt_net_adaptative_object_model_et_ddd&quot;&gt;Original post&lt;/a&gt; blogged on &lt;a href=&quot;http://b2evolution.net/&quot;&gt;b2evolution&lt;/a&gt;.&lt;/small&gt;&lt;/p&gt;&lt;/div&gt;</description>
			<content:encoded><![CDATA[<p>Dans l&#8217;approche Domain Driven Design, le c&#339;ur de la solution c&#8217;est le domaine m&#233;tier. Du point technique le domaine est en g&#233;n&#233;ral une assembly centrale qui est r&#233;f&#233;renc&#233;e par toutes les couches qui gravitent autour du domaine (repository, service, infra, UI, tests unitaires et fonctionnels). Cette d&#233;pendance forte est souvent montr&#233;e du doigt par certains coll&#232;gues pro active record et qui pensent que les donn&#233;es c&#8217;est 90% du business.  Et la question qui pose est : "Souvent" le client  est amen&#233; &#224; faire &#233;voluer ses process et &#224; mettre &#224; jour son m&#233;tier, dans ce cas il faut refaire toute l&#8217;application &#224; cause de cette d&#233;pendance. En g&#233;n&#233;ral je r&#233;ponds que normalement le client change rarement de processus et que le c&#339;ur du m&#233;tier est toujours le m&#234;me, donc l&#8217;&#233;volution &#224; apporter dans le mod&#232;le n&#8217;est pas importante, et en g&#233;n&#233;ral c&#8217;est l&#8217;infrastructure qui change (base de donn&#233;es, fichiers, Service web &#8230; ) et ca on sait g&#233;rer, si l&#8217;impl&#233;mentation des infras sont facilement injectables. Mais admettant que le client revoit ses process et son c&#339;ur de m&#233;tier tout les mois &#8230; que faire ? Je suis all&#233; chercher une r&#233;ponse hier dans la pr&#233;sentation anim&#233;e par Sebastien Ros au sujet de l&#8217;Adaptative Object Model. Et je me suis rendu compte que faire du &#171; DDD adaptable &#187; c&#8217;&#233;tait faisable : En DDD on manipule des entit&#233;s qui ont des propri&#233;t&#233;s, des relations avec d&#8217;autres entit&#233;s, des value type, et contient des comportements  qui encapsule la logique m&#233;tier. Il suffit donc de faire une m&#233;ta description des &#233;l&#233;ments de base pour monter et manipuler un domaine : un customer par exemple est une instance de meta type entit&#233; qui a les propri&#233;t&#233;s suivantes : FirstName, LastName, Address, et une liste de commande. Son comportement se r&#233;sume ainsi : s&#8217;il a d&#233;j&#224; d&#233;pens&#233; 500 euros, il a droit &#224; 10% de remise sur sa prochaine commande. Au-del&#224; des objets du domaine, on peut aussi automatiser la cr&#233;ation des repositories si une entit&#233; est marqu&#233;e par l&#8217;attribut &#171; root  agregate &#187; &#8230; <br />
Imaginons que c&#8217;est faisable, et imaginons qu&#8217;une soci&#233;t&#233; A a rachet&#233; une soci&#233;t&#233; B, et imaginons que soci&#233;t&#233; A et B on d&#233;j&#224; des domaines adaptables (utilisation de l&#8217;AOM dans une optique DDD). La mise en relation des syst&#232;mes d&#8217;information devient simple car il suffit de s&#8217;&#233;changer les m&#233;ta-descriptions respectives de leurs domaines et enfin  d&#8217;appliquer des r&#232;gles de transformation. Par exemple :<br />
Pour la soci&#233;t&#233; A, un customer poss&#232;de les propri&#233;t&#233;s : AddressLine, ZipCode, Country et pour la soci&#233;t&#233; B un Customer a la propri&#233;t&#233; Address. La r&#232;gle &#224; introduire c&#244;t&#233; soci&#233;t&#233; B est : Address = AddressLine +  ZipCode + Country. Toutes ces r&#232;gles sont au niveau des m&#233;ta-descriptions et sont facilement &#233;changeable : Ficher XML par exemple. Mieux encore, si l&#8217;on met en place un monitoring des fichiers de m&#233;ta-description on peut automatiquement mettre &#224; jour les r&#232;gles d&#8217;adaptation  au sein des soci&#233;t&#233;s s&#8217;interfa&#231;ant avec le syst&#232;me.  </p>
<div class="item_footer"><p><small><a href="http://www.dotnetguru2.org/rochdichakroun/index.php/2009/05/20/alt_net_adaptative_object_model_et_ddd">Original post</a> blogged on <a href="http://b2evolution.net/">b2evolution</a>.</small></p></div>]]></content:encoded>
								<comments>http://www.dotnetguru2.org/rochdichakroun/index.php/2009/05/20/alt_net_adaptative_object_model_et_ddd#comments</comments>
			<wfw:commentRss>http://www.dotnetguru2.org/rochdichakroun/index.php?tempskin=_rss2&#38;disp=comments&#38;p=1061</wfw:commentRss>
		</item>
				<item>
			<title>V&#233;lib, Mappoint, et .NET 3.5</title>
			<link>http://www.dotnetguru2.org/rochdichakroun/index.php/2007/11/06/velib_mappoint_et_net_3_5</link>
			<pubDate>Tue, 06 Nov 2007 22:19:50 +0000</pubDate>			<dc:creator>Rochdi Chakroun</dc:creator>
			<category domain="main">.NET Balabala</category>			<guid isPermaLink="false">779@http://www.dotnetguru2.org/</guid>
						<description>&lt;p&gt;Apr&amp;#232;s le d&amp;#233;marrage de velib, plusieurs mashup ont consolid&amp;#233; le service V&amp;#233;lib et  les  services de localisation g&amp;#233;ographique (la majorit&amp;#233; a opt&amp;#233; pour Google Map) afin de permettre aux internautes de localiser les stations v&amp;#233;lib les plus proches et leurs statuts en temps r&amp;#233;el: nombre de v&amp;#233;los, et bornes libres. Un des sites les plus abouti est &lt;a href=&quot;http://www.unvelovite.com/Velib/&quot;&gt;http://www.unvelovite.com/Velib/&lt;/a&gt;&lt;br /&gt;
Le souci avec l&amp;#8217;utilisation des API de Google Map par exemple, est le javascript inclus dans les pages rendues. Ce javascript exclut les utilisateurs mobiles |-|  Or lors des derni&amp;#232;res gr&amp;#232;ves combien d&amp;#8217;entre nous ont souhait&amp;#233; avoir acc&amp;#232;s en fonction de leur position &amp;#224; une carte avec les stations les plus proches et leurs &amp;#233;tats . Pour ceux qui se s&amp;#233;parent pas de leur PC portable et ont une carte d&amp;#8217;acc&amp;#232;s internet 3G+ le probl&amp;#232;me ne se pose pas :&gt;&gt;. &lt;br /&gt;
Bon ! Passons aux choses s&amp;#233;rieuses :&lt;br /&gt;
L&amp;#8217;application, baptis&amp;#233;e VelibLightUp,  doit pouvoir consommer  les services fournis par deux fournisseurs de service : Velib et Mappoint (Si vous vous demandez pourquoi MapPoint et pas GoogleMap la reponse est simple : Vivement Microsoft :&gt;). &lt;br /&gt;
Premier constat Mappoint offre via son service web un grand nombre de services et de classes, il y en a tellement qu&amp;#8217;on risque de ce perdre, donc afin de simplifier la t&amp;#226;che aux couches applicatives sup&amp;#233;rieures,  une facade de MapPoint est de grande utilit&amp;#233;. &lt;br /&gt;
Pour le service V&amp;#233;lib et vu qu&amp;#8217;il est de type REST (http://en.wikipedia.org/wiki/REST) et afin d&amp;#8217;homog&amp;#233;n&amp;#233;iser la consommation de ces services, un Velib proxy nous donnera l&amp;#8217;illusion d&amp;#8217;avoir un web service proxy (classique), ceci va aussi nous permettre de mapper l&amp;#8217;XML rendu par le service Velib &amp;#224; des objets qui auront un sens fonctionnel et qui formeront le domaine velib.&lt;br /&gt;
Ayant la facade MapPoint et le Proxy Velib, on va quand m&amp;#234;me pas laisser la couche pr&amp;#233;sentation ou business manipuler ces deux services. Non ! Un Service Agent s&amp;#8217;impose, c&amp;#8217;est lui qui va consolider les deux fournisseurs de service et offrir aux couches sup&amp;#233;rieures les m&amp;#233;thodes n&amp;#233;cessaires.&lt;br /&gt;
Basta Blabla voyons voir l&amp;#8217;organisation du projet: &lt;br /&gt;
&lt;img src=&quot;http://www.dotnetguru2.org/media/Solution.jpg&quot; border=&quot;0&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Le diagramme de classe du domaine Velib est le suivant, ce domaine  n&amp;#8217;est que le mapping de l&amp;#8217;XML rendu par les services Velib : &lt;br /&gt;
+Le listing de toutes les stations.  &lt;a href=&quot;http://www.velib.paris.fr/service/carto&quot;&gt;http://www.velib.paris.fr/service/carto&lt;/a&gt;&lt;br /&gt;
+Pour une station donn&amp;#233;e il retourne son &amp;#233;tat (v&amp;#233;lo dispo, bornes libres &amp;#8230;) : par exemple pour la station qui a pour id 20020 &lt;a href=&quot;http://www.velib.paris.fr/service/stationdetails/20020&quot;&gt;http://www.velib.paris.fr/service/stationdetails/20020&lt;/a&gt;&lt;br /&gt;
voir le diagramme: &lt;a href=&quot;http://www.dotnetguru2.org/media/diagram.jpg&quot;&gt;http://www.dotnetguru2.org/media/diagram.jpg&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Voyons comment le proxy velib encapsule les appels au service REST :&lt;br /&gt;
Par exemple pour r&amp;#233;cup&amp;#233;rer la liste des stations:&lt;/p&gt;

&lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;
&lt;span class=&quot;rem&quot;&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
&lt;span class=&quot;rem&quot;&gt;/// Return the list of all stations by calling the rest service:&lt;/span&gt;
&lt;span class=&quot;rem&quot;&gt;/// &lt;a href=&quot;http://www.velib.paris.fr/service/carto&quot;&gt;http://www.velib.paris.fr/service/carto&lt;/a&gt;&lt;/span&gt;
&lt;span class=&quot;rem&quot;&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
&lt;span class=&quot;rem&quot;&gt;/// &amp;lt;returns&amp;gt;List of Domain Station&amp;lt;/returns&amp;gt;&lt;/span&gt;
&lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; List&amp;lt;Station&amp;gt; GetStationList()
{
&lt;span class=&quot;rem&quot;&gt;//Opps Linq to XML&lt;/span&gt;
XDocument xDocument =&lt;span class=&quot;kwrd&quot;&gt;null&lt;/span&gt;;
xDocument = XDocument.Load(
    &lt;span class=&quot;str&quot;&gt;&quot;http://www.velib.paris.fr/service/carto&quot;&lt;/span&gt;);
List&amp;lt;Station&amp;gt; stationList = &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; List&amp;lt;Station&amp;gt;();
&lt;span class=&quot;rem&quot;&gt;// call GetDocumentElementByTagName to &lt;/span&gt;
&lt;span class=&quot;rem&quot;&gt;// get only the part of the xDocument holding station data&lt;/span&gt;
var stations = 
    GetDocumentElementByTagName(xDocument,&lt;span class=&quot;str&quot;&gt;&quot;markers&quot;&lt;/span&gt;);
&lt;span class=&quot;rem&quot;&gt;// for each XElement in the Stations to build Station Domain Object&lt;/span&gt;
&lt;span class=&quot;kwrd&quot;&gt;foreach&lt;/span&gt; (XElement element &lt;span class=&quot;kwrd&quot;&gt;in&lt;/span&gt; stations)
{
&lt;span class=&quot;rem&quot;&gt;//Get the station Id&lt;/span&gt;
&lt;span class=&quot;kwrd&quot;&gt;int&lt;/span&gt; stationId = Convert.ToInt32(
    GetAttributeValue(element, &lt;span class=&quot;str&quot;&gt;&quot;number&quot;&lt;/span&gt;));
&lt;span class=&quot;rem&quot;&gt;//Get the Station Name&lt;/span&gt;
&lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt; stationName = 
    GetAttributeValue(element, &lt;span class=&quot;str&quot;&gt;&quot;name&quot;&lt;/span&gt;);
&lt;span class=&quot;rem&quot;&gt;//Get the station address&lt;/span&gt;
&lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt; stationAddress = 
    GetAttributeValue(element, &lt;span class=&quot;str&quot;&gt;&quot;address&quot;&lt;/span&gt;);
&lt;span class=&quot;rem&quot;&gt;//Get the station Full Address&lt;/span&gt;
&lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt; stationFullAddress = 
    GetAttributeValue(element, &lt;span class=&quot;str&quot;&gt;&quot;fullAddress&quot;&lt;/span&gt;);
&lt;span class=&quot;rem&quot;&gt;//Get the station latitude&lt;/span&gt;
&lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt; stationLatitude = 
    GetAttributeValue(element, &lt;span class=&quot;str&quot;&gt;&quot;lat&quot;&lt;/span&gt;);
&lt;span class=&quot;rem&quot;&gt;//Get the station longitude&lt;/span&gt;
&lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt; stationlongitude = 
    GetAttributeValue(element, &lt;span class=&quot;str&quot;&gt;&quot;lng&quot;&lt;/span&gt;);
&lt;span class=&quot;rem&quot;&gt;//Map the station status (open = 1, close = 0)&lt;/span&gt;
StationStatusEnum stationStatus = (StationStatusEnum)
    Convert.ToInt32(GetAttributeValue(element, &lt;span class=&quot;str&quot;&gt;&quot;open&quot;&lt;/span&gt;));
&lt;span class=&quot;rem&quot;&gt;//Build the station Geographic Coordinates &lt;/span&gt;
GeographicCoordinates stationCoordinates;
stationCoordinates = &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; GeographicCoordinates(
                   ConvertStringToDouble(stationlongitude),
                   ConvertStringToDouble(stationLatitude));
&lt;span class=&quot;rem&quot;&gt;//Finaly build a station domain object&lt;/span&gt;
Station station;
station= &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; Station(stationId, stationName, stationAddress,
    stationFullAddress, stationCoordinates, stationStatus);
&lt;span class=&quot;rem&quot;&gt;//Finaly add the station to the list of station&lt;/span&gt;
stationList.Add(station);
}
&lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt; stationList;
}&lt;/pre&gt;


&lt;p&gt;Pour la m&amp;#233;thode GetAttributeValue, qui est appel&amp;#233;e plusieurs fois dans la m&amp;#233;thode pr&amp;#233;c&amp;#233;dente, elle permet de retourner la valeur d&amp;#8217;un attribut en fonction de son nom, le code est le suivant:&lt;/p&gt;

&lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;
&lt;span class=&quot;rem&quot;&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
&lt;span class=&quot;rem&quot;&gt;/// Based on an element and an attribute name return the value of that attribute&lt;/span&gt;
&lt;span class=&quot;rem&quot;&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
&lt;span class=&quot;rem&quot;&gt;/// &amp;lt;param name=&quot;element&quot;&amp;gt;element to fetch in the attribute value&amp;lt;/param&amp;gt;&lt;/span&gt;
&lt;span class=&quot;rem&quot;&gt;/// &amp;lt;param name=&quot;attributeName&quot;&amp;gt;element name&amp;lt;/param&amp;gt;&lt;/span&gt;
&lt;span class=&quot;rem&quot;&gt;/// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;&lt;/span&gt;
&lt;span class=&quot;kwrd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt; GetAttributeValue(
    XElement element, &lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt; attributeName)
{
var query = from attribute &lt;span class=&quot;kwrd&quot;&gt;in&lt;/span&gt; element.Attributes()
            &lt;span class=&quot;kwrd&quot;&gt;where&lt;/span&gt; attribute.Name == attributeName
            select attribute.Value;
List&amp;lt;&lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt;&amp;gt; attibuteValueList = &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; List&amp;lt;&lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt;&amp;gt;(query);
&lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt; (attibuteValueList.Count &amp;gt; 0) 
    ? attibuteValueList[0] : &lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt;.Empty;
}&lt;/pre&gt;

&lt;p&gt;Passons &amp;#224; Mappoint, le code de la m&amp;#233;thode principale GetLocationsMap est le suivant:&lt;/p&gt;

&lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;
&lt;span class=&quot;rem&quot;&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
&lt;span class=&quot;rem&quot;&gt;/// Based on a set of positions, messages return a &lt;/span&gt;
&lt;span class=&quot;rem&quot;&gt;/// map that highlights these positins &lt;/span&gt;
&lt;span class=&quot;rem&quot;&gt;/// and associate a message for each position&lt;/span&gt;
&lt;span class=&quot;rem&quot;&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
&lt;span class=&quot;rem&quot;&gt;/// &amp;lt;param name=&quot;positionList&quot;&amp;gt;List of the positions to place the pushpins&amp;lt;/param&amp;gt;&lt;/span&gt;
&lt;span class=&quot;rem&quot;&gt;/// &amp;lt;param name=&quot;messageList&quot;&amp;gt;list of messages to print on the map (pushpin)&amp;lt;/param&amp;gt;&lt;/span&gt;
&lt;span class=&quot;rem&quot;&gt;/// &amp;lt;param name=&quot;scale&quot;&amp;gt;map scale&amp;lt;/param&amp;gt;&lt;/span&gt;
&lt;span class=&quot;rem&quot;&gt;/// &amp;lt;param name=&quot;width&quot;&amp;gt;Image width&amp;lt;/param&amp;gt;&lt;/span&gt;
&lt;span class=&quot;rem&quot;&gt;/// &amp;lt;param name=&quot;height&quot;&amp;gt;Image width&amp;lt;/param&amp;gt;&lt;/span&gt;
&lt;span class=&quot;rem&quot;&gt;/// &amp;lt;param name=&quot;returnType&quot;&amp;gt;Type of the returned map&amp;lt;/param&amp;gt;&lt;/span&gt;
&lt;span class=&quot;rem&quot;&gt;/// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;&lt;/span&gt;
&lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; MapImage GetLocationsMap(List&amp;lt;LatLong&amp;gt; positionList,
    List&amp;lt;&lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt;&amp;gt; messageList, &lt;span class=&quot;kwrd&quot;&gt;double&lt;/span&gt; scale, &lt;span class=&quot;kwrd&quot;&gt;int&lt;/span&gt; width,
    &lt;span class=&quot;kwrd&quot;&gt;int&lt;/span&gt; height, MapReturnType returnType)
{
&lt;span class=&quot;rem&quot;&gt;// Map point service used to get the map&lt;/span&gt;
RenderServiceSoap renderService = &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; RenderServiceSoap();
&lt;span class=&quot;rem&quot;&gt;//set the user culture&lt;/span&gt;
CultureInfo culture = &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; CultureInfo();
culture.Name = &lt;span class=&quot;str&quot;&gt;&quot;fr&quot;&lt;/span&gt;;
culture.Lcid = 12;
&lt;span class=&quot;rem&quot;&gt;//User info Render Header&lt;/span&gt;
UserInfoRenderHeader userHeader = &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; UserInfoRenderHeader();
userHeader.Culture = culture;
&lt;span class=&quot;rem&quot;&gt;//Set service properties&lt;/span&gt;
renderService.Credentials = GetCredential();
renderService.Timeout = 30000;
renderService.PreAuthenticate = &lt;span class=&quot;kwrd&quot;&gt;true&lt;/span&gt;;
renderService.Credentials = GetCredential();
renderService.UserInfoRenderHeaderValue = userHeader;
&lt;span class=&quot;rem&quot;&gt;//Set the view scale&lt;/span&gt;
ViewByScale[] viewArray = &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; ViewByScale[1];
viewArray[0] = &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; ViewByScale();
viewArray[0].CenterPoint = positionList[0];
viewArray[0].MapScale = scale;
&lt;span class=&quot;rem&quot;&gt;//For each position set a pushpin&lt;/span&gt;
Pushpin[] pinArray = &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; Pushpin[positionList.Count];
&lt;span class=&quot;kwrd&quot;&gt;for&lt;/span&gt; (&lt;span class=&quot;kwrd&quot;&gt;int&lt;/span&gt; i = 0; i &amp;lt; positionList.Count; i++)
{
    pinArray[i] = &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; Pushpin();
    &lt;span class=&quot;rem&quot;&gt;//set the message to associate with the pushpin&lt;/span&gt;
    pinArray[i].Label = messageList[i];
    pinArray[i].PinID = i.ToString();
    &lt;span class=&quot;kwrd&quot;&gt;if&lt;/span&gt; (i == 0)
    {
        &lt;span class=&quot;rem&quot;&gt;//for the first pusshpin it represents the user position&lt;/span&gt;
        &lt;span class=&quot;rem&quot;&gt;//so use a different ICON (RED FLAG)&lt;/span&gt;
        pinArray[i].IconName = &lt;span class=&quot;str&quot;&gt;&quot;29&quot;&lt;/span&gt;;
    }
    &lt;span class=&quot;kwrd&quot;&gt;else&lt;/span&gt;
    {
        &lt;span class=&quot;rem&quot;&gt;//For other position use the default icon&lt;/span&gt;
        pinArray[i].IconName = &lt;span class=&quot;str&quot;&gt;&quot;0&quot;&lt;/span&gt;;
    }
    &lt;span class=&quot;rem&quot;&gt;//set pushpin data source&lt;/span&gt;
    pinArray[i].IconDataSource = &lt;span class=&quot;str&quot;&gt;&quot;MapPoint.Icons&quot;&lt;/span&gt;;
    LatLong latLong = &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; LatLong();
    pinArray[i].LatLong = positionList[i];
}
&lt;span class=&quot;rem&quot;&gt;//Set the map options&lt;/span&gt;
MapOptions options = &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; MapOptions();
ImageFormat imageFormat = &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; ImageFormat();
imageFormat.Height = height;
imageFormat.Width = width;
options.Format = imageFormat;
options.ReturnType = returnType;
&lt;span class=&quot;rem&quot;&gt;// set the map specification&lt;/span&gt;
MapSpecification mapSpecification = &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; MapSpecification();
mapSpecification.Options = options;
mapSpecification.Views = viewArray;
mapSpecification.Pushpins = pinArray;
mapSpecification.DataSourceName = &lt;span class=&quot;str&quot;&gt;&quot;MapPoint.EU&quot;&lt;/span&gt;;
&lt;span class=&quot;rem&quot;&gt;// ouuf finaly call the service&lt;/span&gt;
MapImage[] imageArray = 
                renderService.GetMap(mapSpecification);
&lt;span class=&quot;rem&quot;&gt;// return the first image hoping that we'll get just one :D &lt;/span&gt;
&lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt; imageArray[0];
}
&lt;/pre&gt;

&lt;p&gt;Disons que Map point service et le velib proxy sont finalis&amp;#233;s on passe au Service Agent qui va marier les deux services. la m&amp;#233;thode GetNearStation  prend les param&amp;#232;tres suivants : la rue, le code postal, la ville et pays et retourne une url d&amp;#8217;une image (qu&amp;#8217;on peut afficher sur un mobile par exemple :D ) cette image contient un drapeau rouge qui repr&amp;#233;sente la position de l&amp;#8217;utilisateur et des drapeaux bleus qui correspondent aux stations velib autour de la position de l&amp;#8217;utilisateur. En plus, le statut de chaque station est associ&amp;#233; respectivement &amp;#224; chaque drapeau. Pour limiter la recherche de l&amp;#8217;utilisateur aux stations qui sont les plus proches, on se base sur les coordonn&amp;#233;es g&amp;#233;ographiques de son adresse et on fait varier la latitude et longitude de ~0.03 degr&amp;#233;s. Ce qui donne pour 101 avenue des Champs-Elys&amp;#233;es, 75008:&lt;br /&gt;
&lt;img src=&quot;http://www.dotnetguru2.org/media/demo-small.jpg&quot; border=&quot;0&quot; alt=&quot;&quot; /&gt;&lt;br /&gt;
Pour voir la carte (taille r&amp;#233;elle 800px/800px): &lt;a href=&quot;http://www.dotnetguru2.org/media/demo.gif&quot;&gt;http://www.dotnetguru2.org/media/demo.gif&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Le code de cette m&amp;#233;thode est le suivant:&lt;/p&gt;
&lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;
&lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt; GetNearStation(&lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt; streetAddress, &lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt; postCode,
    &lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt; city, &lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt; country)
{
&lt;span class=&quot;rem&quot;&gt;// List of Station geo-position&lt;/span&gt;
List&amp;lt;LatLong&amp;gt; stationPositionList = 
    &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; List&amp;lt;LatLong&amp;gt;();
&lt;span class=&quot;rem&quot;&gt;//List of station status&lt;/span&gt;
List&amp;lt;StationStatus&amp;gt; stationStatusList = 
    &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; List&amp;lt;StationStatus&amp;gt;();
&lt;span class=&quot;rem&quot;&gt;//List of messages associate with a station&lt;/span&gt;
List&amp;lt;&lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt;&amp;gt; stationInfoList = 
    &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; List&amp;lt;&lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt;&amp;gt;();
&lt;span class=&quot;rem&quot;&gt;// Format the address for Map point service&lt;/span&gt;
&lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt; formatedAddress = 
    FormatAddress(streetAddress, postCode,city, country);
&lt;span class=&quot;rem&quot;&gt;//Init the map point service&lt;/span&gt;
MapPointService service = &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; MapPointService();
&lt;span class=&quot;rem&quot;&gt;//Get the user lat &amp;amp; long&lt;/span&gt;
LatLong addressLatLong = 
    service.GetAddressLatLong(formatedAddress);
&lt;span class=&quot;rem&quot;&gt;//Init the Velib service&lt;/span&gt;
VelibServiceProxy velibServiceProxy = 
    &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; VelibServiceProxy();
&lt;span class=&quot;rem&quot;&gt;//Find the station in the same Arrondissement as the user&lt;/span&gt;
&lt;span class=&quot;rem&quot;&gt;// ~O.OO3 &amp;#176;&lt;/span&gt;
var query = 
from nearStation &lt;span class=&quot;kwrd&quot;&gt;in&lt;/span&gt; velibServiceProxy.GetStationList()
&lt;span class=&quot;kwrd&quot;&gt;where&lt;/span&gt; 
nearStation.Coordinate.Latitude 
    &amp;lt; addressLatLong.Latitude + 0.003 &amp;amp;&amp;amp;
nearStation.Coordinate.Latitude 
    &amp;gt; addressLatLong.Latitude - 0.003 &amp;amp;&amp;amp;
nearStation.Coordinate.Longitude 
    &amp;lt; addressLatLong.Longitude + 0.003 &amp;amp;&amp;amp;
nearStation.Coordinate.Longitude 
    &amp;gt; addressLatLong.Longitude - 0.003
select nearStation;
&lt;span class=&quot;rem&quot;&gt;//Set the list from the query &lt;/span&gt;
List&amp;lt;Station&amp;gt; stationList  = query.ToList&amp;lt;Station&amp;gt;();
&lt;span class=&quot;rem&quot;&gt;//Get Station Info &lt;/span&gt;
stationStatusList = 
    GetStationStatusList(stationList);
&lt;span class=&quot;rem&quot;&gt;//Build the messages&lt;/span&gt;
stationInfoList = 
StartBuildingStationInfoList(stationList);
stationInfoList = 
EndBuildingStationInfoList(stationInfoList, stationStatusList);
&lt;span class=&quot;rem&quot;&gt;//Prepare the list of station lat and long&lt;/span&gt;
&lt;span class=&quot;rem&quot;&gt;//Convert the list of station to LatLong Mappoint &lt;/span&gt;
&lt;span class=&quot;rem&quot;&gt;//object&lt;/span&gt;
stationPositionList = 
stationList.ConvertAll&amp;lt;LatLong&amp;gt;(
&lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; Converter&amp;lt;Station, LatLong&amp;gt;(&lt;span class=&quot;kwrd&quot;&gt;delegate&lt;/span&gt;(Station station)
{
    LatLong latLong = &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; LatLong();
    latLong.Latitude = station.Coordinate.Latitude;
    latLong.Longitude = station.Coordinate.Longitude;
    &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt; latLong;
}));
&lt;span class=&quot;rem&quot;&gt;//Call the GetLocationsByAddress of the mappoint&lt;/span&gt;
&lt;span class=&quot;rem&quot;&gt;// service facade we the appropriate param&lt;/span&gt;
MapImage map = service.GetLocationsByAddress(
    formatedAddress, POSITION_MSG, stationPositionList,
    stationInfoList, 5000, 800, 800, MapReturnType.ReturnUrl);
&lt;span class=&quot;rem&quot;&gt;//Yep! get the img url&lt;/span&gt;
&lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt; map.Url;
}&lt;/pre&gt;

&lt;p&gt;Pour l&amp;#8217;utilisation de cette m&amp;#233;thode par une page aspx il y pas plus simple. En prenant cette page par exemple: &lt;a href=&quot;http://www.dotnetguru2.org/media/aspx.jpg&quot;&gt;http://www.dotnetguru2.org/media/aspx.jpg&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Le code associ&amp;#233; au button click est le suivant:&lt;/p&gt;

&lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;
&lt;span class=&quot;kwrd&quot;&gt;protected&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;void&lt;/span&gt; Button1_Click(&lt;span class=&quot;kwrd&quot;&gt;object&lt;/span&gt; sender, EventArgs e)
{
ServiceFacade service = &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; ServiceFacade();
&lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt; mapUrl = 
service.GetNearStation(TextBox1.Text,
 TextBox2.Text, &lt;span class=&quot;str&quot;&gt;&quot;Paris&quot;&lt;/span&gt;, &lt;span class=&quot;str&quot;&gt;&quot;France&quot;&lt;/span&gt;);
Image1.ImageUrl = mapUrl;
Image1.Visible = &lt;span class=&quot;kwrd&quot;&gt;true&lt;/span&gt;;
}&lt;/pre&gt;

&lt;p&gt;Je vais publier le code sur Codeplex, mais d&amp;#8217;ici l&amp;#224; pour ceux qui veulent avoir le code de la solution (orcas beta 2) ils peuvent me contacter. &lt;/p&gt;







&lt;div class=&quot;item_footer&quot;&gt;&lt;p&gt;&lt;small&gt;&lt;a href=&quot;http://www.dotnetguru2.org/rochdichakroun/index.php/2007/11/06/velib_mappoint_et_net_3_5&quot;&gt;Original post&lt;/a&gt; blogged on &lt;a href=&quot;http://b2evolution.net/&quot;&gt;b2evolution&lt;/a&gt;.&lt;/small&gt;&lt;/p&gt;&lt;/div&gt;</description>
			<content:encoded><![CDATA[<p>Apr&#232;s le d&#233;marrage de velib, plusieurs mashup ont consolid&#233; le service V&#233;lib et  les  services de localisation g&#233;ographique (la majorit&#233; a opt&#233; pour Google Map) afin de permettre aux internautes de localiser les stations v&#233;lib les plus proches et leurs statuts en temps r&#233;el: nombre de v&#233;los, et bornes libres. Un des sites les plus abouti est <a href="http://www.unvelovite.com/Velib/">http://www.unvelovite.com/Velib/</a><br />
Le souci avec l&#8217;utilisation des API de Google Map par exemple, est le javascript inclus dans les pages rendues. Ce javascript exclut les utilisateurs mobiles |-|  Or lors des derni&#232;res gr&#232;ves combien d&#8217;entre nous ont souhait&#233; avoir acc&#232;s en fonction de leur position &#224; une carte avec les stations les plus proches et leurs &#233;tats . Pour ceux qui se s&#233;parent pas de leur PC portable et ont une carte d&#8217;acc&#232;s internet 3G+ le probl&#232;me ne se pose pas :>>. <br />
Bon ! Passons aux choses s&#233;rieuses :<br />
L&#8217;application, baptis&#233;e VelibLightUp,  doit pouvoir consommer  les services fournis par deux fournisseurs de service : Velib et Mappoint (Si vous vous demandez pourquoi MapPoint et pas GoogleMap la reponse est simple : Vivement Microsoft :>). <br />
Premier constat Mappoint offre via son service web un grand nombre de services et de classes, il y en a tellement qu&#8217;on risque de ce perdre, donc afin de simplifier la t&#226;che aux couches applicatives sup&#233;rieures,  une facade de MapPoint est de grande utilit&#233;. <br />
Pour le service V&#233;lib et vu qu&#8217;il est de type REST (http://en.wikipedia.org/wiki/REST) et afin d&#8217;homog&#233;n&#233;iser la consommation de ces services, un Velib proxy nous donnera l&#8217;illusion d&#8217;avoir un web service proxy (classique), ceci va aussi nous permettre de mapper l&#8217;XML rendu par le service Velib &#224; des objets qui auront un sens fonctionnel et qui formeront le domaine velib.<br />
Ayant la facade MapPoint et le Proxy Velib, on va quand m&#234;me pas laisser la couche pr&#233;sentation ou business manipuler ces deux services. Non ! Un Service Agent s&#8217;impose, c&#8217;est lui qui va consolider les deux fournisseurs de service et offrir aux couches sup&#233;rieures les m&#233;thodes n&#233;cessaires.<br />
Basta Blabla voyons voir l&#8217;organisation du projet: <br />
<img src="http://www.dotnetguru2.org/media/Solution.jpg" border="0" alt="" /></p>

<p>Le diagramme de classe du domaine Velib est le suivant, ce domaine  n&#8217;est que le mapping de l&#8217;XML rendu par les services Velib : <br />
+Le listing de toutes les stations.  <a href="http://www.velib.paris.fr/service/carto">http://www.velib.paris.fr/service/carto</a><br />
+Pour une station donn&#233;e il retourne son &#233;tat (v&#233;lo dispo, bornes libres &#8230;) : par exemple pour la station qui a pour id 20020 <a href="http://www.velib.paris.fr/service/stationdetails/20020">http://www.velib.paris.fr/service/stationdetails/20020</a><br />
voir le diagramme: <a href="http://www.dotnetguru2.org/media/diagram.jpg">http://www.dotnetguru2.org/media/diagram.jpg</a></p>

<p>Voyons comment le proxy velib encapsule les appels au service REST :<br />
Par exemple pour r&#233;cup&#233;rer la liste des stations:</p>

<!-- code formatted by http://manoli.net/csharpformat/ -->
<pre class="csharpcode">
<span class="rem">/// &lt;summary&gt;</span>
<span class="rem">/// Return the list of all stations by calling the rest service:</span>
<span class="rem">/// <a href="http://www.velib.paris.fr/service/carto">http://www.velib.paris.fr/service/carto</a></span>
<span class="rem">/// &lt;/summary&gt;</span>
<span class="rem">/// &lt;returns&gt;List of Domain Station&lt;/returns&gt;</span>
<span class="kwrd">public</span> List&lt;Station&gt; GetStationList()
{
<span class="rem">//Opps Linq to XML</span>
XDocument xDocument =<span class="kwrd">null</span>;
xDocument = XDocument.Load(
    <span class="str">"http://www.velib.paris.fr/service/carto"</span>);
List&lt;Station&gt; stationList = <span class="kwrd">new</span> List&lt;Station&gt;();
<span class="rem">// call GetDocumentElementByTagName to </span>
<span class="rem">// get only the part of the xDocument holding station data</span>
var stations = 
    GetDocumentElementByTagName(xDocument,<span class="str">"markers"</span>);
<span class="rem">// for each XElement in the Stations to build Station Domain Object</span>
<span class="kwrd">foreach</span> (XElement element <span class="kwrd">in</span> stations)
{
<span class="rem">//Get the station Id</span>
<span class="kwrd">int</span> stationId = Convert.ToInt32(
    GetAttributeValue(element, <span class="str">"number"</span>));
<span class="rem">//Get the Station Name</span>
<span class="kwrd">string</span> stationName = 
    GetAttributeValue(element, <span class="str">"name"</span>);
<span class="rem">//Get the station address</span>
<span class="kwrd">string</span> stationAddress = 
    GetAttributeValue(element, <span class="str">"address"</span>);
<span class="rem">//Get the station Full Address</span>
<span class="kwrd">string</span> stationFullAddress = 
    GetAttributeValue(element, <span class="str">"fullAddress"</span>);
<span class="rem">//Get the station latitude</span>
<span class="kwrd">string</span> stationLatitude = 
    GetAttributeValue(element, <span class="str">"lat"</span>);
<span class="rem">//Get the station longitude</span>
<span class="kwrd">string</span> stationlongitude = 
    GetAttributeValue(element, <span class="str">"lng"</span>);
<span class="rem">//Map the station status (open = 1, close = 0)</span>
StationStatusEnum stationStatus = (StationStatusEnum)
    Convert.ToInt32(GetAttributeValue(element, <span class="str">"open"</span>));
<span class="rem">//Build the station Geographic Coordinates </span>
GeographicCoordinates stationCoordinates;
stationCoordinates = <span class="kwrd">new</span> GeographicCoordinates(
                   ConvertStringToDouble(stationlongitude),
                   ConvertStringToDouble(stationLatitude));
<span class="rem">//Finaly build a station domain object</span>
Station station;
station= <span class="kwrd">new</span> Station(stationId, stationName, stationAddress,
    stationFullAddress, stationCoordinates, stationStatus);
<span class="rem">//Finaly add the station to the list of station</span>
stationList.Add(station);
}
<span class="kwrd">return</span> stationList;
}</pre>


<p>Pour la m&#233;thode GetAttributeValue, qui est appel&#233;e plusieurs fois dans la m&#233;thode pr&#233;c&#233;dente, elle permet de retourner la valeur d&#8217;un attribut en fonction de son nom, le code est le suivant:</p>

<!-- code formatted by http://manoli.net/csharpformat/ -->
<pre class="csharpcode">
<span class="rem">/// &lt;summary&gt;</span>
<span class="rem">/// Based on an element and an attribute name return the value of that attribute</span>
<span class="rem">/// &lt;/summary&gt;</span>
<span class="rem">/// &lt;param name="element"&gt;element to fetch in the attribute value&lt;/param&gt;</span>
<span class="rem">/// &lt;param name="attributeName"&gt;element name&lt;/param&gt;</span>
<span class="rem">/// &lt;returns&gt;&lt;/returns&gt;</span>
<span class="kwrd">private</span> <span class="kwrd">string</span> GetAttributeValue(
    XElement element, <span class="kwrd">string</span> attributeName)
{
var query = from attribute <span class="kwrd">in</span> element.Attributes()
            <span class="kwrd">where</span> attribute.Name == attributeName
            select attribute.Value;
List&lt;<span class="kwrd">string</span>&gt; attibuteValueList = <span class="kwrd">new</span> List&lt;<span class="kwrd">string</span>&gt;(query);
<span class="kwrd">return</span> (attibuteValueList.Count &gt; 0) 
    ? attibuteValueList[0] : <span class="kwrd">string</span>.Empty;
}</pre>

<p>Passons &#224; Mappoint, le code de la m&#233;thode principale GetLocationsMap est le suivant:</p>

<!-- code formatted by http://manoli.net/csharpformat/ -->
<pre class="csharpcode">
<span class="rem">/// &lt;summary&gt;</span>
<span class="rem">/// Based on a set of positions, messages return a </span>
<span class="rem">/// map that highlights these positins </span>
<span class="rem">/// and associate a message for each position</span>
<span class="rem">/// &lt;/summary&gt;</span>
<span class="rem">/// &lt;param name="positionList"&gt;List of the positions to place the pushpins&lt;/param&gt;</span>
<span class="rem">/// &lt;param name="messageList"&gt;list of messages to print on the map (pushpin)&lt;/param&gt;</span>
<span class="rem">/// &lt;param name="scale"&gt;map scale&lt;/param&gt;</span>
<span class="rem">/// &lt;param name="width"&gt;Image width&lt;/param&gt;</span>
<span class="rem">/// &lt;param name="height"&gt;Image width&lt;/param&gt;</span>
<span class="rem">/// &lt;param name="returnType"&gt;Type of the returned map&lt;/param&gt;</span>
<span class="rem">/// &lt;returns&gt;&lt;/returns&gt;</span>
<span class="kwrd">public</span> MapImage GetLocationsMap(List&lt;LatLong&gt; positionList,
    List&lt;<span class="kwrd">string</span>&gt; messageList, <span class="kwrd">double</span> scale, <span class="kwrd">int</span> width,
    <span class="kwrd">int</span> height, MapReturnType returnType)
{
<span class="rem">// Map point service used to get the map</span>
RenderServiceSoap renderService = <span class="kwrd">new</span> RenderServiceSoap();
<span class="rem">//set the user culture</span>
CultureInfo culture = <span class="kwrd">new</span> CultureInfo();
culture.Name = <span class="str">"fr"</span>;
culture.Lcid = 12;
<span class="rem">//User info Render Header</span>
UserInfoRenderHeader userHeader = <span class="kwrd">new</span> UserInfoRenderHeader();
userHeader.Culture = culture;
<span class="rem">//Set service properties</span>
renderService.Credentials = GetCredential();
renderService.Timeout = 30000;
renderService.PreAuthenticate = <span class="kwrd">true</span>;
renderService.Credentials = GetCredential();
renderService.UserInfoRenderHeaderValue = userHeader;
<span class="rem">//Set the view scale</span>
ViewByScale[] viewArray = <span class="kwrd">new</span> ViewByScale[1];
viewArray[0] = <span class="kwrd">new</span> ViewByScale();
viewArray[0].CenterPoint = positionList[0];
viewArray[0].MapScale = scale;
<span class="rem">//For each position set a pushpin</span>
Pushpin[] pinArray = <span class="kwrd">new</span> Pushpin[positionList.Count];
<span class="kwrd">for</span> (<span class="kwrd">int</span> i = 0; i &lt; positionList.Count; i++)
{
    pinArray[i] = <span class="kwrd">new</span> Pushpin();
    <span class="rem">//set the message to associate with the pushpin</span>
    pinArray[i].Label = messageList[i];
    pinArray[i].PinID = i.ToString();
    <span class="kwrd">if</span> (i == 0)
    {
        <span class="rem">//for the first pusshpin it represents the user position</span>
        <span class="rem">//so use a different ICON (RED FLAG)</span>
        pinArray[i].IconName = <span class="str">"29"</span>;
    }
    <span class="kwrd">else</span>
    {
        <span class="rem">//For other position use the default icon</span>
        pinArray[i].IconName = <span class="str">"0"</span>;
    }
    <span class="rem">//set pushpin data source</span>
    pinArray[i].IconDataSource = <span class="str">"MapPoint.Icons"</span>;
    LatLong latLong = <span class="kwrd">new</span> LatLong();
    pinArray[i].LatLong = positionList[i];
}
<span class="rem">//Set the map options</span>
MapOptions options = <span class="kwrd">new</span> MapOptions();
ImageFormat imageFormat = <span class="kwrd">new</span> ImageFormat();
imageFormat.Height = height;
imageFormat.Width = width;
options.Format = imageFormat;
options.ReturnType = returnType;
<span class="rem">// set the map specification</span>
MapSpecification mapSpecification = <span class="kwrd">new</span> MapSpecification();
mapSpecification.Options = options;
mapSpecification.Views = viewArray;
mapSpecification.Pushpins = pinArray;
mapSpecification.DataSourceName = <span class="str">"MapPoint.EU"</span>;
<span class="rem">// ouuf finaly call the service</span>
MapImage[] imageArray = 
                renderService.GetMap(mapSpecification);
<span class="rem">// return the first image hoping that we'll get just one :D </span>
<span class="kwrd">return</span> imageArray[0];
}
</pre>

<p>Disons que Map point service et le velib proxy sont finalis&#233;s on passe au Service Agent qui va marier les deux services. la m&#233;thode GetNearStation  prend les param&#232;tres suivants : la rue, le code postal, la ville et pays et retourne une url d&#8217;une image (qu&#8217;on peut afficher sur un mobile par exemple :D ) cette image contient un drapeau rouge qui repr&#233;sente la position de l&#8217;utilisateur et des drapeaux bleus qui correspondent aux stations velib autour de la position de l&#8217;utilisateur. En plus, le statut de chaque station est associ&#233; respectivement &#224; chaque drapeau. Pour limiter la recherche de l&#8217;utilisateur aux stations qui sont les plus proches, on se base sur les coordonn&#233;es g&#233;ographiques de son adresse et on fait varier la latitude et longitude de ~0.03 degr&#233;s. Ce qui donne pour 101 avenue des Champs-Elys&#233;es, 75008:<br />
<img src="http://www.dotnetguru2.org/media/demo-small.jpg" border="0" alt="" /><br />
Pour voir la carte (taille r&#233;elle 800px/800px): <a href="http://www.dotnetguru2.org/media/demo.gif">http://www.dotnetguru2.org/media/demo.gif</a></p>

<p>Le code de cette m&#233;thode est le suivant:</p>
<!-- code formatted by http://manoli.net/csharpformat/ -->
<pre class="csharpcode">
<span class="kwrd">public</span> <span class="kwrd">string</span> GetNearStation(<span class="kwrd">string</span> streetAddress, <span class="kwrd">string</span> postCode,
    <span class="kwrd">string</span> city, <span class="kwrd">string</span> country)
{
<span class="rem">// List of Station geo-position</span>
List&lt;LatLong&gt; stationPositionList = 
    <span class="kwrd">new</span> List&lt;LatLong&gt;();
<span class="rem">//List of station status</span>
List&lt;StationStatus&gt; stationStatusList = 
    <span class="kwrd">new</span> List&lt;StationStatus&gt;();
<span class="rem">//List of messages associate with a station</span>
List&lt;<span class="kwrd">string</span>&gt; stationInfoList = 
    <span class="kwrd">new</span> List&lt;<span class="kwrd">string</span>&gt;();
<span class="rem">// Format the address for Map point service</span>
<span class="kwrd">string</span> formatedAddress = 
    FormatAddress(streetAddress, postCode,city, country);
<span class="rem">//Init the map point service</span>
MapPointService service = <span class="kwrd">new</span> MapPointService();
<span class="rem">//Get the user lat &amp; long</span>
LatLong addressLatLong = 
    service.GetAddressLatLong(formatedAddress);
<span class="rem">//Init the Velib service</span>
VelibServiceProxy velibServiceProxy = 
    <span class="kwrd">new</span> VelibServiceProxy();
<span class="rem">//Find the station in the same Arrondissement as the user</span>
<span class="rem">// ~O.OO3 &#176;</span>
var query = 
from nearStation <span class="kwrd">in</span> velibServiceProxy.GetStationList()
<span class="kwrd">where</span> 
nearStation.Coordinate.Latitude 
    &lt; addressLatLong.Latitude + 0.003 &amp;&amp;
nearStation.Coordinate.Latitude 
    &gt; addressLatLong.Latitude - 0.003 &amp;&amp;
nearStation.Coordinate.Longitude 
    &lt; addressLatLong.Longitude + 0.003 &amp;&amp;
nearStation.Coordinate.Longitude 
    &gt; addressLatLong.Longitude - 0.003
select nearStation;
<span class="rem">//Set the list from the query </span>
List&lt;Station&gt; stationList  = query.ToList&lt;Station&gt;();
<span class="rem">//Get Station Info </span>
stationStatusList = 
    GetStationStatusList(stationList);
<span class="rem">//Build the messages</span>
stationInfoList = 
StartBuildingStationInfoList(stationList);
stationInfoList = 
EndBuildingStationInfoList(stationInfoList, stationStatusList);
<span class="rem">//Prepare the list of station lat and long</span>
<span class="rem">//Convert the list of station to LatLong Mappoint </span>
<span class="rem">//object</span>
stationPositionList = 
stationList.ConvertAll&lt;LatLong&gt;(
<span class="kwrd">new</span> Converter&lt;Station, LatLong&gt;(<span class="kwrd">delegate</span>(Station station)
{
    LatLong latLong = <span class="kwrd">new</span> LatLong();
    latLong.Latitude = station.Coordinate.Latitude;
    latLong.Longitude = station.Coordinate.Longitude;
    <span class="kwrd">return</span> latLong;
}));
<span class="rem">//Call the GetLocationsByAddress of the mappoint</span>
<span class="rem">// service facade we the appropriate param</span>
MapImage map = service.GetLocationsByAddress(
    formatedAddress, POSITION_MSG, stationPositionList,
    stationInfoList, 5000, 800, 800, MapReturnType.ReturnUrl);
<span class="rem">//Yep! get the img url</span>
<span class="kwrd">return</span> map.Url;
}</pre>

<p>Pour l&#8217;utilisation de cette m&#233;thode par une page aspx il y pas plus simple. En prenant cette page par exemple: <a href="http://www.dotnetguru2.org/media/aspx.jpg">http://www.dotnetguru2.org/media/aspx.jpg</a></p>

<p>Le code associ&#233; au button click est le suivant:</p>

<!-- code formatted by http://manoli.net/csharpformat/ -->
<pre class="csharpcode">
<span class="kwrd">protected</span> <span class="kwrd">void</span> Button1_Click(<span class="kwrd">object</span> sender, EventArgs e)
{
ServiceFacade service = <span class="kwrd">new</span> ServiceFacade();
<span class="kwrd">string</span> mapUrl = 
service.GetNearStation(TextBox1.Text,
 TextBox2.Text, <span class="str">"Paris"</span>, <span class="str">"France"</span>);
Image1.ImageUrl = mapUrl;
Image1.Visible = <span class="kwrd">true</span>;
}</pre>

<p>Je vais publier le code sur Codeplex, mais d&#8217;ici l&#224; pour ceux qui veulent avoir le code de la solution (orcas beta 2) ils peuvent me contacter. </p>







<div class="item_footer"><p><small><a href="http://www.dotnetguru2.org/rochdichakroun/index.php/2007/11/06/velib_mappoint_et_net_3_5">Original post</a> blogged on <a href="http://b2evolution.net/">b2evolution</a>.</small></p></div>]]></content:encoded>
								<comments>http://www.dotnetguru2.org/rochdichakroun/index.php/2007/11/06/velib_mappoint_et_net_3_5#comments</comments>
			<wfw:commentRss>http://www.dotnetguru2.org/rochdichakroun/index.php?tempskin=_rss2&#38;disp=comments&#38;p=779</wfw:commentRss>
		</item>
				<item>
			<title>1ier  post</title>
			<link>http://www.dotnetguru2.org/rochdichakroun/index.php/2006/09/19/1ier_post</link>
			<pubDate>Tue, 19 Sep 2006 14:55:40 +0000</pubDate>			<dc:creator>Rochdi Chakroun</dc:creator>
			<category domain="main">DotNetGuru</category>			<guid isPermaLink="false">528@http://www.dotnetguru2.org/</guid>
						<description>&lt;p&gt;Voil&amp;#224;, on y est mon premier post !:D&lt;br /&gt;
Sous l&amp;#8217;ampleur de l&amp;#8217;&amp;#233;motion, je me limite &amp;#224; inaugurer mon blog et &amp;#224;  remercier Sami et S&amp;#233;bastien  &amp;#8230; &lt;/p&gt;&lt;div class=&quot;item_footer&quot;&gt;&lt;p&gt;&lt;small&gt;&lt;a href=&quot;http://www.dotnetguru2.org/rochdichakroun/index.php/2006/09/19/1ier_post&quot;&gt;Original post&lt;/a&gt; blogged on &lt;a href=&quot;http://b2evolution.net/&quot;&gt;b2evolution&lt;/a&gt;.&lt;/small&gt;&lt;/p&gt;&lt;/div&gt;</description>
			<content:encoded><![CDATA[<p>Voil&#224;, on y est mon premier post !:D<br />
Sous l&#8217;ampleur de l&#8217;&#233;motion, je me limite &#224; inaugurer mon blog et &#224;  remercier Sami et S&#233;bastien  &#8230; </p><div class="item_footer"><p><small><a href="http://www.dotnetguru2.org/rochdichakroun/index.php/2006/09/19/1ier_post">Original post</a> blogged on <a href="http://b2evolution.net/">b2evolution</a>.</small></p></div>]]></content:encoded>
								<comments>http://www.dotnetguru2.org/rochdichakroun/index.php/2006/09/19/1ier_post#comments</comments>
			<wfw:commentRss>http://www.dotnetguru2.org/rochdichakroun/index.php?tempskin=_rss2&#38;disp=comments&#38;p=528</wfw:commentRss>
		</item>
			</channel>
</rss>
