<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>The World is mine &#187; Spring.net</title>
	<atom:link href="http://grozeille.com/tag/springnet/feed/" rel="self" type="application/rss+xml" />
	<link>http://grozeille.com</link>
	<description>Just another Wordpress.com weblog</description>
	<lastBuildDate>Sat, 07 Jan 2012 12:00:31 +0000</lastBuildDate>
	<language>fr</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='grozeille.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://s2.wp.com/i/buttonw-com.png</url>
		<title>The World is mine &#187; Spring.net</title>
		<link>http://grozeille.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://grozeille.com/osd.xml" title="The World is mine" />
	<atom:link rel='hub' href='http://grozeille.com/?pushpress=hub'/>
		<item>
		<title>Spring.Net, ASP.Net, Session et multithreadind</title>
		<link>http://grozeille.com/2010/10/24/spring-net-asp-net-session-et-multithreadind/</link>
		<comments>http://grozeille.com/2010/10/24/spring-net-asp-net-session-et-multithreadind/#comments</comments>
		<pubDate>Sun, 24 Oct 2010 19:22:00 +0000</pubDate>
		<dc:creator>Mathias Kluba</dc:creator>
				<category><![CDATA[Développement]]></category>
		<category><![CDATA[.Net]]></category>
		<category><![CDATA[Asp.net]]></category>
		<category><![CDATA[Spring.net]]></category>

		<guid isPermaLink="false">https://grozeille.wordpress.com/?p=452</guid>
		<description><![CDATA[Pour commencer, je vous préviens, ce billet s’adresse à ceux qui savent développer en ASP.Net. Je ne plaisante pas! J’ai vu un trop grand nombre de gens prétendre savoir faire des applications Web sans savoir m’expliquer le protocole HTTP! Donc voici un petit test d’entré: Comment fonctionne un HttpHandler? Pourquoi ne pas utiliser les UpdatePanels? [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=grozeille.com&#038;blog=173450&#038;post=452&#038;subd=grozeille&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Pour commencer, je vous préviens, ce billet s’adresse à ceux qui savent développer en ASP.Net.<br />
Je ne plaisante pas! J’ai vu un trop grand nombre de gens prétendre savoir faire des applications Web sans savoir m’expliquer le protocole HTTP!<br />
Donc voici un petit test d’entré:</p>
<ul>
<li>Comment fonctionne un HttpHandler?</li>
<li>Pourquoi ne pas utiliser les UpdatePanels?</li>
<li>A quoi sert un MembershipProvider et comment s’en servir?</li>
</ul>
<p>Si ces questions vous paressent obscures et que vous êtes plutôt un développeur “glisser-déposer”, alors je vous propose de vous “glisser-déposer” sur un autre blog <img src='http://s1.wp.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>Pour les autres, j’ai un aveu à vous faire: je viens de découvrir qu’il n’est pas possible d’afficher 2 pages ASP.Net en simultané si elles accèdent à la Session.</p>
<p><span id="more-452"></span></p>
<p>J’ai cru que j’étais sous l’effet d’une drogue… mais non, c’était bien vrai.<br />
J’ai alors voulu en avoir le cœur net, et j’ai fouillé de nombreux forums… c’est la que j’ai découvert que d’autres l’on découvert après 5 ans d’expériences en ASP.Net!!!</p>
<p>Certes, on ouvre rarement 2 pages Web d’un même site, mais il est plus fréquent d’avoir 2 appelles Ajax en simultané.<br />
C’est mon cas, car j’aime Ajax, j’aime le Web, et j’utilise une technique “Comet” appelé “Long Pooling”. Cela consiste à faire un appelle Ajax potentiellement infinie, qui va se terminé seulement si le serveur à quelque chose à nous dire. Cela permet d’avoir un système de notification très simple à implémenter.</p>
<p>Pour vulgariser, au lieu d’avoir ça:</p>
<blockquote><p>Client: “Tu veux me dire quelque chose?”<br />
Server: “Non”<br />
Client: “Tu veux me dire quelque chose?”<br />
Server: “Non”<br />
Client: “Tu veux me dire quelque chose?”<br />
Server: “Mais lâche moi sale client!!!”</p></blockquote>
<p>En long polling ça donne ça:</p>
<blockquote><p>Client: “Bon, tu me préviens si t’as un truc à me dire&#8230;”<br />
Server: “&#8230;”<br />
Server: “&#8230;”<br />
Server: “&#8230;”<br />
Server: “&#8230;”<br />
Server: “&#8230; ouai, j’ai un truc pour toi, un nouveau message”<br />
Client: “OK, je le traite, bon, tu me préviens si t’as un autre truc à me dire&#8230;”</p></blockquote>
<p>Et sinon, en C# ça donne ça:</p>
<p><pre class="brush: csharp;">
public string LongAjaxCall()
{
    string result = null

    while(result == null)
    {
        lock(this.notificationList)
        {
            if(notificationList.Count &gt; 0)
            {
                result = new JavaScriptSerializer().Serialize(this.notificationList.ToArray());
                this.notificationList.Clear();
            }
        }
        if(result == null)
            Thread.Sleep(500);
    }
}
</pre></p>
<p>En général, le serveur n’a pas les mêmes choses à dire aux différents clients, c’est pourquoi on utilise la Session. Mais cette dernière est verrouillée par le long pooling, l’utilisateur ne sera alors pas en mesure d’ouvrir une nouvelle page si l’appelle Ajax ne se termine pas, ce qui est plutôt fâcheux.</p>
<h2>Et Spring.Net dans tout ça?</h2>
<p>J’utilise massivement Spring.net, pas seulement pour l’IOC, mais pour bien d’autres choses que ce merveilleux framework offre.<br />
Dans le cadre d’une application Web, il est possible d’avoir un “scope” pour les instances des objets:</p>
<ul>
<li><strong>application</strong>: un singleton pour toute l’application Web</li>
<li><strong>session</strong>: l’instance n’existe que dans le cadre d’une session ASP.Net</li>
<li><strong>request</strong>: l’instance n’existe pour pour la duré de la requête HTTP</li>
</ul>
<p>J’utilise pas mal le scope “Session”, afin d’instancier des “contrôleurs” différents pour chaque utilisateurs. Je peux ainsi conserver un état à l’aide des membres de mes contrôleurs (ou conserver une connexion SQL, etc.).</p>
<p>Je vous propose alors de jeter un œil à mon exemple afin de comprendre mon problème: <a href="http://bitbucket.org/grozeille/testaspsessionmultithread/src">http://bitbucket.org/grozeille/testaspsessionmultithread/src</a><br />
Cette solution contient un premier exemple “<a href="http://bitbucket.org/grozeille/testaspsessionmultithread/src/tip/TestASPSessionMultithread.Bad/">TestASPSessionMultithread.Bad</a>” qui illustre mon problème.</p>
<p>L’exemple est simple:<br />
Vous avez une première page “<em>Default.aspx</em>” qui permet d’ajouter une “<em>string</em>” à une liste à l’aide du button “<em>add</em>” qui effectuera un appelle Ajax.<br />
Vous pouvez alors ensuite déclencher un “<em>long pooling</em>” à partir du boutton “<em>long polling</em>” qui va demander au serveur de renvoyer les nouveaux items.</p>
<p style="text-align:center;"><a href="http://grozeille.files.wordpress.com/2010/10/image.png"></a><a href="http://grozeille.files.wordpress.com/2010/10/longpooling01.png"><img class="aligncenter size-medium wp-image-462" style="border:1px solid black;" title="LongPooling01" src="http://grozeille.files.wordpress.com/2010/10/longpooling01.png?w=300&h=231" alt="" width="300" height="231" /></a></p>
<p>Dans cet ordre, tout va bien. Par contre, si vous faite un “<em>long pooling</em>” en premier, le boutton “<em>add</em>” restera bloqué et il sera donc impossible d’ajouter un nouvel item.</p>
<p style="text-align:center;"><a href="http://grozeille.files.wordpress.com/2010/10/longpooling02.png"><img class="aligncenter size-medium wp-image-463" style="border:1px solid black;" title="LongPooling02" src="http://grozeille.files.wordpress.com/2010/10/longpooling02.png?w=300&h=260" alt="" width="300" height="260" /></a></p>
<p>De même, vous pouvez tester aussi la page “<em>Other.aspx</em>” qui simule un lourd traitement qui prend 5 secondes. Quand vous essayer d’ouvrir la page “<em>Other</em>” et que vous tentez de recharger la page “<em>Default</em>” en parallèle, cette dernière va attendre la fin du chargement de la page “<em>Other</em>”.</p>
<p style="text-align:center;"><a href="http://grozeille.files.wordpress.com/2010/10/longpooling03.png"><img class="aligncenter size-medium wp-image-464" style="border:1px solid black;" title="LongPooling03" src="http://grozeille.files.wordpress.com/2010/10/longpooling03.png?w=300&h=140" alt="" width="300" height="140" /></a></p>
<p>A noter aussi que j’affiche le <em>“creation time</em>” des différents contrôleurs. Puisque Spring.Net permet d’avoir du <span style="text-decoration:underline;">LazyLoad</span>, on voit que le <em>OtherController </em>est créé après le <em>DefaultController</em>.</p>
<p>Si vous regardez le code en détail, vous pouvez voir que je gère les appelles Ajax à l’aide d’un <em>HttpHandler </em>custom.<br />
Je pense que le code est suffisamment bien commenté pour le comprendre, et pour ceux qui ont la flemme de récupérer le source depuis BitBucket, voici l’extrait:</p>
<p><pre class="brush: csharp;">
public class BadAjaxHttpHandler : IHttpHandler, IRequiresSessionState
{
    public void ProcessRequest(HttpContext context)
    {
        // get the name of the controller and the action from the URL
        var action = context.Request.Url.Segments[context.Request.Url.Segments.Length - 1];
        var controller = context.Request.Url.Segments[context.Request.Url.Segments.Length - 2]
            .Replace(&quot;.ajax&quot;, string.Empty)
            .Replace(&quot;/&quot;, string.Empty);

        // get the instance of the controller thanks to its name
        var instance = ContextRegistry.GetContext().GetObject(controller);

        // get the method of the controller thanks to reflection
        var method = instance.GetType().GetMethod(action, BindingFlags.Instance | BindingFlags.Public);
        var args = new List();
        foreach (var item in method.GetParameters())
        {
            args.Add(TypeDescriptor.GetConverter(item.ParameterType).ConvertFromString(context.Request.Params[item.Name]));
        }

        // invoke the method of the controller
        var result = method.Invoke(instance, args.ToArray());

        // return the JSON value of the method result
        context.Response.Write(new JavaScriptSerializer().Serialize(result));
        context.Response.StatusCode = 200;
        context.Response.End();
</pre></p>
<p>On remarque que pour accéder à la session nous avons ici besoin d’implémenter l’interface “<em>IRequiresSessionState</em>”, mais la aussi, comme c’est en lecture/écriture, cela verrouille la session le temps de la requête HTTP.</p>
<h2>Comment résoudre le problème?</h2>
<p>La solution est dans le projet “<a href="http://bitbucket.org/grozeille/testaspsessionmultithread/src/tip/TestASPSessionMultithread.Good.Unsecured/">02-TestASPSessionMultithread.Good.Unsecured</a>”.</p>
<p>Pourquoi “Unsecured” ? On verra ça plus tard.</p>
<p>La solution est simple, il suffit d’accéder à la Session en “lecture seule”.<br />
En effet, il peut être problématique d’ajouter une même clé depuis 2 thread concurrents, mais une fois que la clé est créée, c’est à vous de gérer la concurrence de la valeur.</p>
<p>Exemple:</p>
<p><pre class="brush: csharp;">
Session[“list”] = new List(); // problème de concurrence, donc session verrouillée

((List)Session[“list”]).Add(“toto”); // ce cas est une lecture seule de la session, mais à vous de gérer la concurrence pour la collection
</pre></p>
<p>Comme Spring.Net est en quelque sorte une “grosse collection d’instance”, et que Sprint.net utilise une seule clé “spring.object”, cela s’applique aussi <img src='http://s0.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Par défaut, les pages sont en accès Write à la session. Pour changer cela, il faut ajouter une option dans l’ASPX:</p>
<p><pre class="brush: xml;">
&lt;%@ Page EnableSessionState=&quot;ReadOnly&quot;  %&gt;
</pre></p>
<p>Il a fallut un petit changement dans le HttpHandler Ajax aussi:</p>
<p><pre class="brush: csharp;">
public class AjaxHttpHandler : IHttpHandler, IReadOnlySessionState
</pre></p>
<p>Cette nouvelle interface “<em>IReadOnlySessionState</em>” parle d’elle même <img src='http://s0.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Et voila! C’est tout! Ca marche, plus de problème de concurrence!<br />
Enfin… non ce n’est pas tout, on a un petit problème, c’est que Sprint.net ne pourra plus jamais initialiser la session sans accès en écriture <img src='http://s0.wp.com/wp-includes/images/smilies/icon_sad.gif' alt=':(' class='wp-smiley' /><br />
Il faut donc trouver un “bootstrap” qui accède à la session en écriture juste le temps de créer le contexte Spring.Net.</p>
<p>L’astuce est donc de faire une redirection vers un HttpHandler particulier “<em>SpringSessionHttpHandler</em>” si la session est nouvelle. Il peut alors accèder à la session en écriture grâce à l’interface “IRequiresSessionState” pour initialiser le contexte et rediriger vers la page d’origine.</p>
<p>Ceci est fait lors du “<em>OnLoad</em>” car nos pages héritent de “<em>SessionPage</em>”.</p>
<p><pre class="brush: csharp;">
public class SessionPage : Page
{
    protected override void OnLoad(EventArgs e)
    {
        // build the spring.net session
        if (Session.IsNewSession)
        Response.Redirect(&quot;SpringSessionHttpHandler?ReturnUrl=&quot; + Server.UrlEncode(Request.Url.ToString()), true);

        base.OnLoad(e);
    }
}
</pre></p>
<p>Le code du HttpHandler est très simple: il force la création du contexte Spring dans la session, puis redirige sur la page d’origine qui elle a un accès en lecture seule sur la session.</p>
<p><pre class="brush: csharp;">
public class BadAjaxHttpHandler : IHttpHandler, IRequiresSessionState
    {
        public void ProcessRequest(HttpContext context)
        {
            // get the name of the controller and the action from the URL
            var action = context.Request.Url.Segments[context.Request.Url.Segments.Length - 1];
            var controller = context.Request.Url.Segments[context.Request.Url.Segments.Length - 2]
                .Replace(&quot;.ajax&quot;, string.Empty)
                .Replace(&quot;/&quot;, string.Empty);

            // get the instance of the controller thanks to its name
            var instance = ContextRegistry.GetContext().GetObject(controller);

            // get the method of the controller thanks to reflection
            var method = instance.GetType().GetMethod(action, BindingFlags.Instance | BindingFlags.Public);
            var args = new List&lt;object&gt;();
            foreach (var item in method.GetParameters())
            {
                args.Add(TypeDescriptor.GetConverter(item.ParameterType).ConvertFromString(context.Request.Params[item.Name]));
            }

            // invoke the method of the controller
            var result = method.Invoke(instance, args.ToArray());

            // return the JSON value of the method result
            context.Response.Write(new JavaScriptSerializer().Serialize(result));
            context.Response.StatusCode = 200;
            context.Response.End();
        }
</pre></p>
<h2>Mais quel astuce géniale! &#8230;mais pourquoi “Unsecured” ?</h2>
<p>Vous pouvez remarquer que j’affiche l’ID de la session dans la page.<br />
L’identifiant de session est stocké par défaut dans un cookie. J&#8217;ai tout de même changé le nom de ce dernier, car si je laisse la valeur par défaut, je risque d’avoir un conflit avec une autre application (erreur de débutant)</p>
<p><pre class="brush: xml;">
&lt;sessionState cookieName=&quot;TestSession&quot;/&gt;
</pre></p>
<p>Normalement, le cookie est “sécurisé”, cad qu’il n’est pas accessible depuis du Javascript malicieux.<br />
Mais bon, un cookie ça reste quand même pas super sécurisé.</p>
<p>Si vous voulez tester un vol de session, il vous suffit de copier/coller l’ID de la session dans un cookie d’un autre navigateur.</p>
<p>Comment faire alors pour sécuriser le tout? Vous avez pour cela différentes solutions:</p>
<ul>
<li>implémenter votre propre gestion d’ID de session avec &lt;sessionState customProvider=&#8221;MonType&#8221;&gt;, et vérifier l’identité à l’aide de critère comme l’IP du client</li>
<li>coupler la session avec l’authentification</li>
</ul>
<p>C’est cette dernière solution que je vais vous présenter, car c’est la plus simple.<br />
L’authentification en ASP.Net se fait à l’aide du MembershipProvider, que vous pouvez implémenter vous même. Le framework .Net va alors gérer l’identité à l’aide d’un cookie aussi, mais ce dernier est beaucoup plus sécurisé et vous pouvez y faire confiance.<br />
Je vais alors stocker dans la session la valeur du cookie d’authentification, et vérifier donc l’identité avant d’accéder à la session.</p>
<p>Vous pouvez vérifiez cela par vous même à l’aide du projet <a href="http://bitbucket.org/grozeille/testaspsessionmultithread/src/tip/TestASPSessionMultithread.Good.Secured/">03-TestASPSessionMultithread.Good.Secured</a><br />
Si vous tentez de voler le cookie d’authentification pour l’utiliser sur un autre navigateur, vous serez alors déconnecté. Si vous tentez de voler le cookie de session, vous serez alors aussi déconnecté.</p>
<p>Les pages hérites alors de “<em>SecuredSessionPage</em>”, et vont alors vérifier le cookie de session dans le &#8220;<em>OnLoad</em>&#8220;:</p>
<p><pre class="brush: csharp;">
// if the user tried to steal the session of another user
if (Page.Request.Cookies[FormsAuthentication.FormsCookieName] == null ||
    !Equals(Page.Request.Cookies[FormsAuthentication.FormsCookieName].Value, Session[FormsAuthentication.FormsCookieName]))
{
    this.Logout();
}
</pre></p>
<p>Je vous laisse ensuite découvrir l&#8217;implémentation de l&#8217;authentification, mais ce n&#8217;est pas le sujet de ce billet et il n&#8217;y a rien de plus classique.</p>
<h2>Conclusion</h2>
<p>Si comme moi vous utiliser Spring.net avec ASP.net et que vous avez des problèmes de lenteur, essayer cette astuce <img src='http://s0.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<br /> Tagged: <a href='http://grozeille.com/tag/net/'>.Net</a>, <a href='http://grozeille.com/tag/aspnet/'>Asp.net</a>, <a href='http://grozeille.com/tag/springnet/'>Spring.net</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/grozeille.wordpress.com/452/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/grozeille.wordpress.com/452/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/grozeille.wordpress.com/452/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/grozeille.wordpress.com/452/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/grozeille.wordpress.com/452/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/grozeille.wordpress.com/452/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/grozeille.wordpress.com/452/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/grozeille.wordpress.com/452/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/grozeille.wordpress.com/452/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/grozeille.wordpress.com/452/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/grozeille.wordpress.com/452/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/grozeille.wordpress.com/452/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/grozeille.wordpress.com/452/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/grozeille.wordpress.com/452/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=grozeille.com&#038;blog=173450&#038;post=452&#038;subd=grozeille&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://grozeille.com/2010/10/24/spring-net-asp-net-session-et-multithreadind/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/fcf307a3a2899d162cabfd41241f17b9?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">grozeille</media:title>
		</media:content>

		<media:content url="http://grozeille.files.wordpress.com/2010/10/longpooling01.png?w=300" medium="image">
			<media:title type="html">LongPooling01</media:title>
		</media:content>

		<media:content url="http://grozeille.files.wordpress.com/2010/10/longpooling02.png?w=300" medium="image">
			<media:title type="html">LongPooling02</media:title>
		</media:content>

		<media:content url="http://grozeille.files.wordpress.com/2010/10/longpooling03.png?w=300" medium="image">
			<media:title type="html">LongPooling03</media:title>
		</media:content>
	</item>
		<item>
		<title>Présentation de Spring.Net</title>
		<link>http://grozeille.com/2010/06/23/presentation-de-spring-net/</link>
		<comments>http://grozeille.com/2010/06/23/presentation-de-spring-net/#comments</comments>
		<pubDate>Wed, 23 Jun 2010 20:48:00 +0000</pubDate>
		<dc:creator>Mathias Kluba</dc:creator>
				<category><![CDATA[ALT.Net]]></category>
		<category><![CDATA[.Net]]></category>
		<category><![CDATA[Spring.net]]></category>

		<guid isPermaLink="false">http://grozeille.com/?p=364</guid>
		<description><![CDATA[Je remercie David Coppet, Florent Dugué, Olivier Bazoud, Ophélie Rudent, ALT.Net, le SUG, Zenika, et l&#8217;équipe de France pour m&#8217;avoir permis de présenter Spring.Net. C&#8217;était hier, dans les locaux de Zenika: http://www.eventbrite.com/event/727568176 Mais comme vous êtes nombreux à ne pas avoir pu y assister, et que certains d&#8217;entre vous souhaites consulter les sources des démos, [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=grozeille.com&#038;blog=173450&#038;post=364&#038;subd=grozeille&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Je remercie David Coppet, Florent Dugué, Olivier Bazoud, Ophélie Rudent, ALT.Net, le SUG,  Zenika, et l&#8217;équipe de France pour m&#8217;avoir permis de présenter Spring.Net.</p>
<p>C&#8217;était hier, dans les locaux de Zenika: <a href="http://www.eventbrite.com/event/727568176">http://www.eventbrite.com/event/727568176</a></p>
<p>Mais comme vous êtes nombreux à ne pas avoir pu y assister, et que certains d&#8217;entre vous souhaites consulter les sources des démos, je vous proposes de télécharger le tout sur mon Bitbucket: <a href="http://bitbucket.org/grozeille/spring.demo/src">http://bitbucket.org/grozeille/spring.demo/src</a></p>
<p>J&#8217;espère que ça vous a plus, et que cela vous a permis de découvrir de nouvelles choses dans Spring.Net.<br />
Si des gens d&#8217;ALT.Net  souhaite que je refasse la présentation à une date moins problématique, n&#8217;hésitez par à me le faire savoir.<br />
De même, si vous souhaitez que j&#8217;approfondisse un sujet en prenant plus de temps à expliquer les démos, ce serait avec plaisir.</p>
<iframe src='http://www.slideshare.net/slideshow/embed_code/4591254' width='630' height='516'></iframe>
<p><a href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fgrozeille.com%2F2010%2F06%2F23%2Fpresentation-de-spring-net%2F&amp;linkname=Pr%C3%A9sentation%20de%20Spring.Net"><img src="http://static.addtoany.com/buttons/share_save_256_24.png" alt="Share" /></a></p>
<br /> Tagged: <a href='http://grozeille.com/tag/net/'>.Net</a>, <a href='http://grozeille.com/tag/alt-net/'>ALT.Net</a>, <a href='http://grozeille.com/tag/springnet/'>Spring.net</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/grozeille.wordpress.com/364/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/grozeille.wordpress.com/364/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/grozeille.wordpress.com/364/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/grozeille.wordpress.com/364/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/grozeille.wordpress.com/364/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/grozeille.wordpress.com/364/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/grozeille.wordpress.com/364/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/grozeille.wordpress.com/364/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/grozeille.wordpress.com/364/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/grozeille.wordpress.com/364/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/grozeille.wordpress.com/364/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/grozeille.wordpress.com/364/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/grozeille.wordpress.com/364/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/grozeille.wordpress.com/364/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=grozeille.com&#038;blog=173450&#038;post=364&#038;subd=grozeille&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://grozeille.com/2010/06/23/presentation-de-spring-net/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/fcf307a3a2899d162cabfd41241f17b9?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">grozeille</media:title>
		</media:content>

		<media:content url="http://static.addtoany.com/buttons/share_save_256_24.png" medium="image">
			<media:title type="html">Share</media:title>
		</media:content>
	</item>
		<item>
		<title>Spring.Fluent</title>
		<link>http://grozeille.com/2010/01/04/spring-fluent/</link>
		<comments>http://grozeille.com/2010/01/04/spring-fluent/#comments</comments>
		<pubDate>Mon, 04 Jan 2010 21:51:23 +0000</pubDate>
		<dc:creator>Mathias Kluba</dc:creator>
				<category><![CDATA[Spring.Fluent]]></category>
		<category><![CDATA[.Net]]></category>
		<category><![CDATA[Spring.net]]></category>

		<guid isPermaLink="false">http://grozeille.com/?p=222</guid>
		<description><![CDATA[Certains le savent déjà, je suis un accro à Spring.Net depuis ses débuts. En fait, je suis devenu amoureux de Spring Java dès sa sortie&#8230; c&#8217;était les débuts de l&#8217;IOC. Spring est devenu un framework &#8220;standard de facto&#8221; dans le monde Java. Il inclut bien plus que de l&#8217;IOC: AOP, Web MVC, etc. Aujourd&#8217;hui, Spring [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=grozeille.com&#038;blog=173450&#038;post=222&#038;subd=grozeille&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Certains le savent déjà, je suis un accro à <a href="http://www.springframework.net/">Spring.Net</a> depuis ses débuts.<br />
En fait, je suis devenu amoureux de Spring Java dès sa sortie&#8230; c&#8217;était les débuts de l&#8217;IOC.</p>
<p><a href="http://www.springsource.com/">Spring</a> est devenu un framework &#8220;standard de facto&#8221; dans le monde Java. Il inclut bien plus que de l&#8217;IOC: AOP, Web MVC, etc.<br />
Aujourd&#8217;hui, Spring c&#8217;est aussi un serveur &#8220;JEE&#8221; d&#8217;un nouveau genre. Puis il y a eu l&#8217;acquisition d&#8217;Hyperic, puis c&#8217;est au tour de VMWare d&#8217;acquérir Spring&#8230;<br />
Bref, c&#8217;est une vrai success story dans le monde Java.</p>
<p>Quand à Spring.Net, ce n&#8217;est pas encore ça. Le <a href="http://www.castleproject.org/">projet Castle</a> est même lui plus avancé: framework IOC, AOP, Web MVC, etc.<br />
Je crois que Castle était en avance sur son temps dans l&#8217;écosystème .Net, c&#8217;est peut-être la raison pourquoi il n&#8217;a pas pris la même ampleur que Spring Java.</p>
<p>Mais j&#8217;ai foie en Spring! Ce framework m&#8217;aide tout les jours à réaliser des <strong>applications d&#8217;entreprises</strong> complexes et robustes.</p>
<p>Mais une chose rebute TOUT développeur .Net: la configuration XML.<br />
Le XML c&#8217;est verbeux, le XML ça ne se compile pas, on n&#8217;a pas intellisense avec le XML&#8230;<br />
Bref, plein de raison de préférer des frameworks comme <a href="http://code.google.com/p/autofac/">AutoFac</a> ou <a href="http://ninject.org/">Ninject</a> qui propose une approche de configuration par code, voir à la sauce &#8220;fluent&#8221;.</p>
<p>A ça, je réponds que:</p>
<ul>
<li>la verbosité n&#8217;est pas dramatique quand on a la complétion. Je remarque aussi que la verbosité est reproché avec des fichiers XML de 1000 lignes&#8230; ce qui est tout aussi vrai avec un code source C# de 1000 lignes.</li>
<li>la complétion et la vérification du XML peut être faite à l&#8217;édition ou la compilation, c&#8217;est ce que fait  <a href="http://springide.org/blog/">Spring IDE</a> sous Eclipse, mais pas de support VisualStudio pour le moment (même si <a href="http://www.jetbrains.com/resharper/">Resharper</a> <a href="http://www.springframework.net/docs/1.3.0/reference/html/vsnet.html#d4e9692">arrive à la rescousse</a>)</li>
<li>on <strong>PEUT</strong> faire du Spring sans XML, même si les gens de Spring.Net n&#8217;ont pas été très cool sur l&#8217;API&#8230;</li>
</ul>
<p>Comme l&#8217;API de Spring.Net est un peut obscure et pas très documenté sur son utilisation en dehors d&#8217;une configuration XML, j&#8217;ai décidé de faire une petite surcouche pour facilité l&#8217;écriture et que ce soit suffisamment intuitif pour ne pas avoir besoin d&#8217;une doc.</p>
<p><strong>De cette volonté est né le projet </strong><a href="http://github.com/grozeille/Spring.Fluent/"><strong>Spring.Fluent</strong></a><strong>!!</strong></p>
<p>C&#8217;est un projet OpenSource, ce qui veut dire que je ne vous interdit pas de m&#8217;aider à réaliser mon rêve <img src='http://s0.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /><br />
Ceci-dit, un projet similaire existe déjà: <a href="http://code.google.com/p/fluent-spring/">http://code.google.com/p/fluent-spring/<br />
</a>Alors pourquoi faire un fork? Car il m&#8217;a fallut 1 journée pour faire autant et même plus que ce le projet propose, et à ma façon qui me plait rien qu&#8217;à moi!</p>
<p>De plus, Mark Pollack à l&#8217;annonce de Spring.Net 1.3, a prétendu que la configuration &#8220;par code Fluent&#8221; sera un point de la prochaine version, à savoir la 2.0: <a href="http://www.infoq.com/interviews/Spring.NET-1.3-2.0">http://www.infoq.com/interviews/Spring.NET-1.3-2.0</a></p>
<p>Je souhaite à Mark et toutes l&#8217;équipe de Spring.Net de réussir, en attendant j&#8217;ai ma propre solution. Et si elle peut les inspirer pour Spring.Net 2.0, ce sera formidable. C&#8217;est pourquoi je pense ce cet &#8220;effort&#8221; n&#8217;est pas perdu: il n&#8217;est jamais inutile de contribuer au monde OpenSource et à faire connaitre ses opinions.</p>
<br /> Tagged: .Net, Spring.net <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/grozeille.wordpress.com/222/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/grozeille.wordpress.com/222/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/grozeille.wordpress.com/222/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/grozeille.wordpress.com/222/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/grozeille.wordpress.com/222/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/grozeille.wordpress.com/222/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/grozeille.wordpress.com/222/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/grozeille.wordpress.com/222/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/grozeille.wordpress.com/222/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/grozeille.wordpress.com/222/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/grozeille.wordpress.com/222/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/grozeille.wordpress.com/222/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/grozeille.wordpress.com/222/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/grozeille.wordpress.com/222/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=grozeille.com&#038;blog=173450&#038;post=222&#038;subd=grozeille&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://grozeille.com/2010/01/04/spring-fluent/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/fcf307a3a2899d162cabfd41241f17b9?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">grozeille</media:title>
		</media:content>
	</item>
		<item>
		<title>Les Settings en .Net</title>
		<link>http://grozeille.com/2008/06/08/les-settings-en-net/</link>
		<comments>http://grozeille.com/2008/06/08/les-settings-en-net/#comments</comments>
		<pubDate>Sun, 08 Jun 2008 17:33:32 +0000</pubDate>
		<dc:creator>Mathias Kluba</dc:creator>
				<category><![CDATA[Développement]]></category>
		<category><![CDATA[.Net]]></category>
		<category><![CDATA[settings]]></category>
		<category><![CDATA[Spring.net]]></category>
		<category><![CDATA[xml]]></category>

		<guid isPermaLink="false">http://grozeille.wordpress.com/?p=60</guid>
		<description><![CDATA[La plateforme .Net fournit un mécanisme pour gérer les paramétrages. Il en existe 2 types : ceux de l&#8217;application et ceux de l&#8217;utilisateur. Au début de l&#8217;existance, il y avait la bonne vielle méthode du fichier *.ini, mais aujourd&#8217;hui le XML et devenu LE standard pour écrire des données dans un fichier &#8220;lisible&#8221; et structuré. [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=grozeille.com&#038;blog=173450&#038;post=60&#038;subd=grozeille&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>La plateforme .Net fournit un mécanisme pour gérer les paramétrages. Il en existe 2 types : ceux de l&#8217;application et ceux de l&#8217;utilisateur. Au début de l&#8217;existance, il y avait la bonne vielle méthode du fichier *.ini, mais aujourd&#8217;hui le XML et devenu LE standard pour écrire des données dans un fichier &#8220;lisible&#8221; et structuré.</p>
<p>Il existe un autre standard : les applications .Net possède un fichier &#8220;mon_application.exe.config&#8221; qui n&#8217;est autre qu&#8217;un XML contenant le paramétrage de l&#8217;appliation. Ce fichier est structuré en 2 grosses parties: l&#8217;entête avec la section &#8220;configSections&#8221; qui décrit les sections du XML et les &#8220;parser&#8221; qui vont lire ces dernières. Puis il y a les sections proprement dites.<br />
<span id="more-60"></span></p>
<p>Quand on veut utiliser des settings de l&#8217;application de type &#8220;clef=valeur&#8221;, on peut les renseigner dans la section &#8220;applicationSettings&#8221;. On peut ainsi facilement créer un paramétrage de l&#8217;application mais aussi pour chaque utilisateur à l&#8217;aide de la section &#8220;userSettings&#8221;.<br />
Voici un exemple de paramétrage:</p>
<p><pre class="brush: xml;">
&lt;userSettings&gt;
	&lt;MonApp.Settings&gt;
		&lt;setting name=&quot;PreferredLanguage&quot; serializeAs=&quot;String&quot;&gt;
			&lt;value&gt;fr-FR&lt;/value&gt;
		&lt;/setting&gt;
	&lt;/MonApp.Settings&gt;
&lt;/userSettings&gt;
&lt;applicationSettings&gt;
	&lt;MonApp.Settings&gt;
		&lt;setting name=&quot;TimeShowMsg&quot; serializeAs=&quot;String&quot;&gt;
			&lt;value&gt;5&lt;/value&gt;
		&lt;/setting&gt;
		&lt;setting name=&quot;NotepadPath&quot; serializeAs=&quot;String&quot;&gt;
			&lt;value&gt;c:\windows\notepad.exe&lt;/value&gt;
		&lt;/setting&gt;
	&lt;/MonApp.Settings&gt;
&lt;/applicationSettings&gt;
</pre></p>
<p>VisualStudio propose une technique simple pour manipuler ces paramétrage. Il permet de créer un fichier &#8220;.settings&#8221; qui va tout simplement générer une classe pour accéder à tout ça, et qui va aussi permettre de sauvegarder les settings de l&#8217;utilisateur courant (dans un .config séparé dans C:\Documents and Settings\UserName\Local Settings\AppName\).<br />
<pre class="brush: csharp;">
// on récupère la valeur d'une clef très simplement
String value = Settings.Default.MyKey;
// si elle a comme scope &quot;user&quot;, on peut la modifier et la sauvegarder
Settings.Default.MyKey= value;
Settings.Default.Save();
</pre></p>
<p>Pour ma part, j&#8217;utilise massivement Spring.net et ses XML. Mes objets possèdent souvent des attributs qui ressemble à des paramètres (j&#8217;externalise au maximum). De plus, Spring.net propose de référencer d&#8217;autre XML, ce qui me permet de découper mon paramétrage en plusieurs fichiers pour différent domaine (Logging, Base de données, etc).<br />
<pre class="brush: xml;">
&lt;!-- dans le App.config --&gt;
&lt;objects xmlns=&quot;http://www.springframework.net&quot;&gt;
  &lt;import resource=&quot;logging.xml&quot;/&gt;
  &lt;import resource=&quot;database.xml&quot;/&gt;;
  &lt;import resource=&quot;general.xml&quot;/&gt;
&lt;/objects&gt;
</pre><br />
<pre class="brush: xml;">
&lt;!-- dans general.xml --&gt;
&lt;objects xmlns=&quot;http://www.springframework.net&quot;&gt;
  &lt;object id=&quot;Setting&quot; type=&quot;MonApp.Setting, MonApp&quot;&gt;
    &lt;property name=&quot;Timeout&quot; value=&quot;100&quot;/&gt;
  &lt;/object&gt;
&lt;/objects&gt;
</pre><br />
Mais il est vrai qu&#8217;un XML de Spring n&#8217;est pas facile à lire, car il ressemble à un code C# avec une suite de construction de classes. Il peut devenir vite complexe s&#8217;il y a beaucoup de classes de relations entre eux, ou si on utilise des concepts avancés de Spring.net (ObjectFactory par exemple).</p>
<p>Une des solutions les plus élégante pour un public informaticien, est de créer ses propres balises XML Spring.net, comme celles déjà existantes (Exemple: <a href="http://www.springframework.net/doc-latest/reference/html/dbprovider.html#d0e11738">paramétrage de base de données</a>.) On masque ainsi la complexité de la construction du programme en laissant une grande souplesse. Mais cette solution demande un certain effort dans la réalisation du parser XML.<br />
<pre class="brush: xml;">
&lt;objects xmlns='http://www.springframework.net'
             xmlns:custom=&quot;http://www.grozeillle.com/custom&quot;&gt;
  &lt;custom:Setting timeout=&quot;100&quot;&gt;
    &lt;custom:EmbededSetting name=&quot;Default&quot;&gt;
      &lt;!-- autres settings --&gt;
    &lt;/custom:EmbededSetting/&gt;
  &lt;/custom:Setting&gt;
&lt;/objects&gt;
</pre><br />
Mais ces fichiers de paramétrages restent difficiles à lire pour une personne non-informaticienne, qui n&#8217;a pas besoin de savoir comment le programme est construit. Dans ce cas, on externalise des valeurs dans des fichiers &#8220;.properties&#8221; très lisible puisque c&#8217;est une simple fichier texte avec une liste de couples &#8220;clef=valeur&#8221;. On peut aussi externaliser ces couples dans une XML mais on perd l&#8217;intérêt d&#8217;avoir quelque chose de très facile à lire.<br />
<pre class="brush: xml;">
&lt;objects xmlns='http://www.springframework.net'&gt;
&lt;!-- Cet objet contient une liste de &quot;fournisseur&quot; de paramétres--&gt;
  &lt;object type=&quot;Spring.Objects.Factory.Config.VariablePlaceholderConfigurer, Spring.Core&quot;&gt;
	&lt;property name=&quot;VariableSources&quot;&gt;
	  &lt;list&gt;
		&lt;!-- Nous n'avons ici qu'un seul fournisseur, 
			qui va chercher les paramétrages dans un fichier .properties --&gt;
		&lt;object type=&quot;Spring.Objects.Factory.Config.PropertyFileVariableSource, Spring.Core&quot;&gt;
		  &lt;!- la liste de nos fichiers .properties --&gt;
		  &lt;property name=&quot;Locations&quot;&gt;
			&lt;list&gt;
			  &lt;value&gt;config.properties&lt;/value&gt;
			&lt;/list&gt;
		  &lt;/property&gt;
		&lt;/object&gt;
	  &lt;/list&gt;
	&lt;/property&gt;
  &lt;/object&gt;
&lt;/objects&gt;
</pre></p>
<p>On peut ainsi utiliser des variables comme ceci:<br />
<pre class="brush: xml;">
&lt;objects xmlns='http://www.springframework.net'&gt;
	&lt;!-- mon object de type &quot;MyTutoClass&quot; a besoin du chemin de Notepad.exe --&gt;
	&lt;object type=&quot;MyApp.MyTutoClass, MyApp&quot;&gt;
		&lt;property name=&quot;NotepadPath&quot; value=&quot;${notepad.path}&quot;&gt;
	&lt;/object&gt;
&lt;/objects&gt;
</pre></p>
<p>Mon fichier .properties ressemble simplement à ça:<br />
<pre class="brush: vb;">
;ceci est un commentaire
notepad.path=c:\windows\notepad.exe
</pre></p>
<p>Spring.net propose plusieurs méthodes de recherche de ces clef+valeur. On peut avoir comme source des fichiers &#8220;.properties&#8221;, mais aussi la section &#8220;settings&#8221; dans l&#8217;App.config (comme vu plus haut), la base de Registre, etc. Voici la liste dans la <a href="http://www.springframework.net/doc-latest/reference/html/objects.html#objects-variablesource">documentation officiel</a>. Si elle ne vous suffit pas, vous pouvez toujours créer votre &#8220;provider&#8221; vous même.</p>
<p>Enfin, pour les plus &#8220;hardcore&#8221; d&#8217;entre-vous (ceux qui aime recoder l&#8217;univers), vous pouvez aussi créer votre propre XML avec votre propre format. Il est vrai qu&#8217;on souhaite parfois faire sa propre classe &#8220;Setting&#8221; car on veut hiérarchiser les différents paramètres. Admettons que l&#8217;on veuille vraiment avoir son propre format de fichier XML, ceci reste très simple en .Net:<br />
<pre class="brush: csharp;">
// créer un &quot;serializer&quot; de Setting
XmlSerializer serializer = new XmlSerializer(typeof(Setting));
// création d'un flux sur mon fichier XML
TextWriter writer = new StreamWriter(&quot;Settings.xml&quot;);
// création de ma classe de Setting
Setting setting = new Setting();
// setting.Timeout = 5; etc, etc..
// enfin, sauvegarde de mon objet sous format XML dans le flux de mon fichier &quot;Settings.xml&quot;
serializer.Serialize(writer, setting);
</pre></p>
<p>On ne peut pas faire plus simple, non? Et vous savez quoi? Par défaut, ça marche sans rien faire d&#8217;autre. Mais si vous voulez customizer le format du XML, il suffira de décorer notre classe Setting à l&#8217;aide de quelques attributs [XmlAttribute]. Si vous voulez générer un schéma XSD de ce format XML, c&#8217;est à l&#8217;aide de <code>c:\Program Files\Microsoft SDKs\Windows\v6.0A\bin\xsd.exe</code>.</p>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/grozeille.wordpress.com/60/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/grozeille.wordpress.com/60/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/grozeille.wordpress.com/60/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/grozeille.wordpress.com/60/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/grozeille.wordpress.com/60/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/grozeille.wordpress.com/60/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/grozeille.wordpress.com/60/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/grozeille.wordpress.com/60/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/grozeille.wordpress.com/60/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/grozeille.wordpress.com/60/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/grozeille.wordpress.com/60/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/grozeille.wordpress.com/60/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/grozeille.wordpress.com/60/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/grozeille.wordpress.com/60/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/grozeille.wordpress.com/60/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/grozeille.wordpress.com/60/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=grozeille.com&#038;blog=173450&#038;post=60&#038;subd=grozeille&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://grozeille.com/2008/06/08/les-settings-en-net/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/fcf307a3a2899d162cabfd41241f17b9?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">grozeille</media:title>
		</media:content>
	</item>
		<item>
		<title>Timeout WCF au bout d&#8217;un certain nombre d&#8217;appels</title>
		<link>http://grozeille.com/2008/04/30/timeout-wcf-au-bout-dun-certain-nombre-dappels/</link>
		<comments>http://grozeille.com/2008/04/30/timeout-wcf-au-bout-dun-certain-nombre-dappels/#comments</comments>
		<pubDate>Wed, 30 Apr 2008 23:20:52 +0000</pubDate>
		<dc:creator>Mathias Kluba</dc:creator>
				<category><![CDATA[Développement]]></category>
		<category><![CDATA[.Net]]></category>
		<category><![CDATA[Asp.net]]></category>
		<category><![CDATA[Spring.net]]></category>
		<category><![CDATA[tips]]></category>
		<category><![CDATA[WCF]]></category>

		<guid isPermaLink="false">http://grozeille.wordpress.com/?p=50</guid>
		<description><![CDATA[Rien de plus stressant que de passer une journée entière sur un bug. Surtout si on n&#8217;a aucune idée du problème (pas d&#8217;exceptions, ni d&#8217;erreurs dans les logs) et que les recherches sur Internet sont infructueuses. Contexte : une application Web Asp.Net communique avec un service WCF. Problème : au bout d’un certain nombre d’appels [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=grozeille.com&#038;blog=173450&#038;post=50&#038;subd=grozeille&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Rien de plus stressant que de passer une journée entière sur un bug. Surtout si on n&#8217;a aucune idée du problème (pas d&#8217;exceptions, ni d&#8217;erreurs dans les logs) et que les recherches sur Internet sont infructueuses.<br />
<strong>Contexte</strong> : une application Web Asp.Net communique avec un service WCF.<br />
<strong>Problème</strong> : au bout d’un certain nombre d’appels (invariant) l’application Web n’arrive plus à joindre le serveur (Timeout).</p>
<p><span id="more-50"></span>Pour conserver une trace de mon incompétence, voici donc la <strong>solution</strong>:<br />
Pour qu&#8217;on puisse dialoguer avec un service WCF dans une page Asp.net, je leur injecte un proxy à l’aide de Spring (voir <a href="http://www.springframework.net/doc-latest/reference/html/web.html#web-di">Spring.net pour le web</a>). Pour cela, j’utilise une &#8220;factory de proxy&#8221; à l’aide de l’interface <a href="http://www.springframework.net/doc-latest/reference/html/objects.html#d0e4032">IFactoryObject</a>.<br />
Crédule que j’étais, j’imaginais que le fait de retourner <code>true</code> pour la propriété <code>IsSingleton</code> allait faire en sorte que Spring.net ne fasse appel qu’une seule fois à la méthode <code>GetObject()</code>.<br />
Et bien non ! C&#8217;est à vous d’être cohérent: même si <code>IsSingleton</code> retourne <code>true</code>,  rien ne vous empêche de toujours retourner une instance différente dans la méthode <code>GetObject()</code>.</p>
<p>Pour en revenir à mon problème, vous l’aurez compris : ma méthode <code>GetObject()</code> retournait à chaque fois un nouveau proxy vers le service WCF.<br />
<strong>Résulat</strong> : à chaque fois que Spring avait besoin d’injecter mon proxy à une page (postback par exemple), je créai une nouvelle connexion au serveur WCF. J&#8217;ai fini par atteindre le nombre de connexion max, et le serveur ne répondait plus.</p>
<p>Il est tout de même dommage que les <a href="http://msdn.microsoft.com/en-us/library/ms732023.aspx">traces WCF</a> ne m&#8217;ont pas révélé d&#8217;exception expliquant cette limite max de connexion <img src='http://s0.wp.com/wp-includes/images/smilies/icon_sad.gif' alt=':(' class='wp-smiley' /> </p>
<p>Pour approfondir le sujet sur les <code>IFactoryObject</code> :<br />
Un objet qui implémente <code>IFactoryObject</code> doit toujours être un singleton, si ce n’est pas le cas on obtient une exception:<br />
<pre class="brush: xml;">
&lt;object id=&quot;maFactory&quot; type=&quot;MonAssembly.MaFactory, MonAssembly&quot; singleton=&quot;false&quot;/&gt;
</pre><br />
<code><br />
=&gt; IFactoryObject must be defined as a singleton - IFactoryObjects themselves are not allowed to be prototypes.<br />
</code></p>
<p>La propriété <code>IsSingleton</code> de la factory indique seulement ce qu’elle est censée faire&#8230; mais sans aucune obligation/vérification du comportement. Dans mon cas, je retournais <code>true</code> mais rien ne m&#8217;a empêché de créer une nouvelle instance à chaque appel&#8230;</p>
<p>Dans le cas particulier d&#8217;une application Asp.net, on peut avoir des &#8220;presque singleton&#8221; en changeant le <code>scope</code>:<br />
<pre class="brush: xml;">
&lt;object id=&quot;maFactory&quot; type=&quot;MonAssembly.MaFactory, MonAssembly&quot; scope=&quot;application&quot;/&gt;
</pre></p>
<ul>
<li>scope=&#8221;application&#8221; : c&#8217;est un singleton de toute l&#8217;application web. Firefox et Safari m&#8217;affiche toujours 1.</li>
<li>scope=&#8221;session&#8221; : c&#8217;est un singleton pour chaque session cliente. Firefox et Safari m&#8217;affiche toujours 2 (1 instance pour Firefox +  1 instance pour Safari).</li>
<li>scope=&#8221;request&#8221; : c&#8217;est un singleton dans le cadre de la requête. Firefox et Safari vois le compteur s&#8217;incrémenter à chaque rafraichissement de la page.</li>
</ul>
<p>Pour <a href="http://www.springframework.net/doc-latest/reference/html/objects.html#d0e2577">plus d&#8217;infos sur les scopes</a>.</p>
<p><strong>Conclusion(s)</strong> :</p>
<ol>
<li>Ce n&#8217;est pas la propriété <code>IsSingleton</code> qui détermine si Spring va faire appelle une ou plusieurs fois à votre Factory. C&#8217;est à elle de fournir le comportement adéquat.</li>
<li>Un singleton n&#8217;en est pas toujours un&#8230; ça dépend du contexte. Dans tous les cas, pour éviter les erreurs comme la mienne, n&#8217;oublier pas d&#8217;utiliser la <code>destroyMethod</code> pour libérer les ressources. (l&#8217;interface <code>ILifeCycle</code> de Java <a href="http://jira.springframework.org/browse/SPRNET-753">n&#8217;existe pas encore</a> dans Spring.net  mais la <a href="http://www.springframework.net/roadmap.html">1.2 sort en RC1 début mai</a>&#8230;).</li>
<li>Un &#8220;Timeout&#8221; peut vouloir dire &#8220;trop de connexion au serveur&#8221; <img src='http://s0.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </li>
<li>Cette fameuse Factory de proxy WCF sera fournie dans Spring.net 1.2. j&#8217;aurais perdu moins de temps en <a href="http://forum.springframework.net/showthread.php?t=2936">prenant les sources des nightbuilds</a>&#8230; vive l&#8217;OpenSource!</li>
</ol>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/grozeille.wordpress.com/50/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/grozeille.wordpress.com/50/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/grozeille.wordpress.com/50/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/grozeille.wordpress.com/50/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/grozeille.wordpress.com/50/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/grozeille.wordpress.com/50/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/grozeille.wordpress.com/50/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/grozeille.wordpress.com/50/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/grozeille.wordpress.com/50/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/grozeille.wordpress.com/50/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/grozeille.wordpress.com/50/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/grozeille.wordpress.com/50/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/grozeille.wordpress.com/50/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/grozeille.wordpress.com/50/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/grozeille.wordpress.com/50/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/grozeille.wordpress.com/50/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=grozeille.com&#038;blog=173450&#038;post=50&#038;subd=grozeille&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://grozeille.com/2008/04/30/timeout-wcf-au-bout-dun-certain-nombre-dappels/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/fcf307a3a2899d162cabfd41241f17b9?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">grozeille</media:title>
		</media:content>
	</item>
		<item>
		<title>Utiliser des *.resx externes (avec Spring.net)</title>
		<link>http://grozeille.com/2008/04/27/utiliser-des-resx-externes-avec-springnet/</link>
		<comments>http://grozeille.com/2008/04/27/utiliser-des-resx-externes-avec-springnet/#comments</comments>
		<pubDate>Sun, 27 Apr 2008 19:19:38 +0000</pubDate>
		<dc:creator>Mathias Kluba</dc:creator>
				<category><![CDATA[Développement]]></category>
		<category><![CDATA[.Net]]></category>
		<category><![CDATA[I18N]]></category>
		<category><![CDATA[Spring.net]]></category>

		<guid isPermaLink="false">http://grozeille.wordpress.com/?p=32</guid>
		<description><![CDATA[On a parfois besoin de livrer une application .Net avec les fichiers de ressources, afin qu&#8217;un traducteur, voir même un intégrateur, puisse faire les traductions au dernier moment. Si cette personne doit recompiler l&#8217;application pour voir le fruit de son travail, ce n&#8217;est pas très pratique voir impossible: allez lui expliquer que VisualStudio n&#8217;est pas [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=grozeille.com&#038;blog=173450&#038;post=32&#038;subd=grozeille&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>On a parfois besoin de livrer une application .Net avec les fichiers de ressources, afin qu&#8217;un traducteur, voir même un intégrateur, puisse faire les traductions au dernier moment.</p>
<p>Si cette personne doit recompiler l&#8217;application pour voir le fruit de son travail, ce n&#8217;est pas très pratique voir impossible: allez lui expliquer que VisualStudio n&#8217;est pas nécessaire et qu&#8217;il est possible de créer des ressources avec <a href="http://msdn2.microsoft.com/fr-fr/library/ccec7sz1(VS.80).aspx">ResGen.exe</a> (et <a href="http://msdn2.microsoft.com/fr-fr/library/c405shex(VS.80).aspx">al.exe</a> pour faire des <a href="http://msdn2.microsoft.com/fr-fr/library/sb6a8618(VS.80).aspx">assembly satellites</a>). Très franchement, les traducteurs ne veulent pas de quelque chose d&#8217;aussi et vont vous fuir comme la peste si vous leur demander d&#8217;être des développeurs.</p>
<p><span id="more-32"></span>La solution est donc d&#8217;utiliser simplement des fichier *.resx sans les compiler, et elle a plusieurs avantages:</p>
<ul>
<li>le traducteur n&#8217;a pas à savoir comment compiler des ressources (ce n&#8217;est pas un développeur)</li>
<li>les fichiers *.resx sont sous la forme XML, et donc (très?) lisible (la structure propose même un champ &#8220;commentaire&#8221;)</li>
<li>il existe bien sûr des éditeurs de fichiers *.resx pour ceux qui ne veulent même pas savoir ce que XML veut dire: <a href="http://www.aisto.com/roeder/dotnet/">Resourcer for .net</a></li>
</ul>
<p>Vous pouvez retrouver ces explication sur <a href="http://blechie.com/WPierce/archive/2007/08/01/Using-Resx-Files-with-a-ResourceManager.aspx">le blog suivant</a>. <a href="http://blechie.com/WPierce/archive/2007/08/01/Using-Resx-Files-with-a-ResourceManager.aspx"><br />
</a>Et Oh joie! Ce blog explique comment réaliser un <code>ResourceManager</code> personnalisé capable de charger des fichiers .resx! C&#8217;est donc tous ce qu&#8217;il nous faut, nul besoin de réinventer un autre mécanisme de traduction maison.</p>
<p>Pour pousser la réflexion plus loin, je voulais utiliser Spring.net pour obtenir la traduction. Cette solution à pour avantage de ne passer que par le contexte pour obtenir cette dernière, peut importe dans quel fichier elle se trouve. Il suffit alors de paramétrer dans le fichier <code>App.Config</code> le chemin de chaque fichier *.resx.</p>
<p>Pour ce faire, rien de plus facile: Spring.net fournit une classe qui recense un certain nombre de <code>ResourceManager</code>. En référençant donc notre <code>ResxResourceManager</code> qui pointe sur notre fichier *.resx, le contexte Spring sera alors capable de fournir les bonnes traductions si on l&#8217;interroge. Pour obtenir une traduction dans la culture courante, il suffira alors d&#8217;écrire ceci:<br />
<pre class="brush: csharp;">
ContextRegistry.GetContext().GetMessage(&quot;MaClef&quot;);
</pre><br />
Le XML de configuration ressemble à ça:<br />
<pre class="brush: xml;">
&lt;object name=&quot;messageSource&quot; type=&quot;Spring.Context.Support.ResourceSetMessageSource, Spring.Core&quot;&gt;
  &lt;property name=&quot;ResourceManagers&quot;&gt;
    &lt;list&gt;
      &lt;!-- ResourceManager qui pointe sur notre fichier Resx\MyResource.resx --&gt;
      &lt;object id=&quot;MyResource&quot; type=&quot;TestWinformsRessources.ResxResourceManager&quot;&gt;
        &lt;constructor-arg name=&quot;baseName&quot; value=&quot;MyResource&quot;/&gt;
        &lt;constructor-arg name=&quot;resourceDir&quot; value=&quot;Resx&quot;/&gt;
      &lt;/object&gt;
    &lt;/list&gt;
  &lt;/property&gt;
&lt;/object&gt;
</pre><br />
Vous pouvez voire concrètement ce que ça donne avec <a href="http://www.box.net/shared/al00ws8w0s">un petit exemple</a>.</p>
<p><a href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2fgrozeille.wordpress.com%2f2008%2f04%2f27%2futiliser-des-resx-externes-avec-springnet%2f"><img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fgrozeille.wordpress.com%2f2008%2f04%2f27%2futiliser-des-resx-externes-avec-springnet%2f&amp;border=6699cc&amp;bgcolor=99cc66&amp;cbgcolor=f3f6ec" border="0" alt="kick it on DotNetKicks.com" /></a></p>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/grozeille.wordpress.com/32/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/grozeille.wordpress.com/32/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/grozeille.wordpress.com/32/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/grozeille.wordpress.com/32/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/grozeille.wordpress.com/32/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/grozeille.wordpress.com/32/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/grozeille.wordpress.com/32/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/grozeille.wordpress.com/32/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/grozeille.wordpress.com/32/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/grozeille.wordpress.com/32/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/grozeille.wordpress.com/32/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/grozeille.wordpress.com/32/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/grozeille.wordpress.com/32/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/grozeille.wordpress.com/32/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/grozeille.wordpress.com/32/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/grozeille.wordpress.com/32/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=grozeille.com&#038;blog=173450&#038;post=32&#038;subd=grozeille&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://grozeille.com/2008/04/27/utiliser-des-resx-externes-avec-springnet/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/fcf307a3a2899d162cabfd41241f17b9?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">grozeille</media:title>
		</media:content>

		<media:content url="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fgrozeille.wordpress.com%2f2008%2f04%2f27%2futiliser-des-resx-externes-avec-springnet%2f&#38;border=6699cc&#38;bgcolor=99cc66&#38;cbgcolor=f3f6ec" medium="image">
			<media:title type="html">kick it on DotNetKicks.com</media:title>
		</media:content>
	</item>
	</channel>
</rss>
