<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-1146316188254265608</id><updated>2011-11-27T02:39:47.800+01:00</updated><category term='Afterthought'/><category term='AOP'/><category term='Dojo'/><category term='Visual Studio'/><category term='Claymore'/><category term='SQL'/><category term='CSS'/><category term='Javascript'/><category term='SMDBehavior'/><category term='Virtual Earth'/><category term='MVP'/><category term='Google Charts'/><category term='CIL'/><category term='MSBuild'/><category term='Blogger'/><category term='IIS'/><category term='Mercurial'/><category term='EntityFramework.Patterns'/><category term='ASP.NET MVC'/><category term='ASP.NET'/><category term='Autre'/><category term='SignalR'/><category term='WCF'/><category term='Subsonic'/><category term='Micro Framework'/><category term='GreaseMonkey'/><category term='ORM'/><category term='SSAS'/><category term='SSRS'/><category term='Nuget'/><category term='Electronique'/><category term='SSIS'/><category term='AllyStats'/><category term='Mono.Cecil'/><category term='Obsidian'/><category term='Entity Framework'/><category term='OGame'/><title type='text'>Memory Leaks</title><subtitle type='html'>Blog sur les technos Microsoft.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://mymemoryleaks.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1146316188254265608/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://mymemoryleaks.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Fabrice Michellonet</name><uri>http://www.blogger.com/profile/10201820062243684793</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_yYUu3sWKdtU/SE76j2im4AI/AAAAAAAACFA/OgO15yojzu8/S220/Fabrice_MICHELLONET.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>49</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-1146316188254265608.post-4921929042336737796</id><published>2011-10-14T13:58:00.000+02:00</published><updated>2011-10-17T15:47:00.765+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ASP.NET'/><title type='text'>Implémenter une sécurité à base de rôles avec Windows Authentication &amp; SQL Server</title><content type='html'>&lt;br /&gt;
Ces derniers jours j'ai été confronté à une problématique très intéressante; j'aimerais la partager avec vous aujourd'hui et vous soumettre la solution que j'ai imaginé pour y répondre.&lt;br /&gt;
&lt;br /&gt;
Mon client souhaitait restreindre l'accès à son site/application intranet aux seuls membres d'un groupe Windows prédéfini. &lt;br /&gt;
Le hic est que le site fonctionne avec des rôles définis en base de données, laissant ainsi libre champs aux admins de l'appli d'attribuer et révoquer des droits aux autres utilisateurs. Évidement, il était hors de question de devoir passer par l'IT pour changer les droits des utilisateurs à l'avenir.&lt;br /&gt;
&lt;br /&gt;
Si l'on transpose la demande en termes techniques, on a besoin du &lt;a href="http://msdn.microsoft.com/fr-fr/library/system.web.security.windowstokenroleprovider.aspx"&gt;WindowsTokenRoleProvider&lt;/a&gt; pour autoriser l'accès au site et pour tout le reste il faut se reposer sur un &lt;a href="http://msdn.microsoft.com/fr-fr/library/system.web.security.sqlroleprovider.aspx"&gt;SqlRoleProvider&lt;/a&gt;.&lt;br /&gt;
Comme vous le savez, ce genre de configuration n'est pas prise en charge par le modèle de provider tel que nous le connaissons jusqu'à présent.&lt;br /&gt;
&lt;br /&gt;
En cherchant sur la toile si ce genre de situation à déjà été traitée (ne réinventons pas la roue carrée), vous tomberez très certainement sur &lt;a href="http://weblogs.asp.net/scottgu/pages/Recipe_3A00_-Implementing-Role_2D00_Based-Security-with-ASP.NET-2.0-using-Windows-Authentication-and-SQL-Server.aspx"&gt;un article de Scott Guthrie&lt;/a&gt; qui traite d'un problème très similaire. Dans l'article &lt;a href="http://weblogs.asp.net/scottgu/"&gt;l'homme à la chemise rouge&lt;/a&gt; nous montre comment, sans code, utiliser les rôles issus de la base de données et n'autoriser l'accès au site &lt;u&gt;qu'aux utilisateurs identifiés&lt;/u&gt;. Et c'est bien sur ce dernier point que nos problématiques diffèrent car dans mon cas, il ne suffit pas d'être identifié sur le domaine, mais il faut aussi faire partie d'un groupe d'utilisateurs.&lt;br /&gt;
&lt;br /&gt;
J'ai donc remonté mes manches, et quitte à écrire du code j'ai tenté de trouver une solution générique permettant de combiner des RoleProvider.&lt;br /&gt;
&lt;br /&gt;
Commençons par définir un RoleProviderDecorator qui comme son nom l'indique suit le pattern &lt;a href="http://en.wikipedia.org/wiki/Decorator_pattern"&gt;Decorator&lt;/a&gt;.&lt;br /&gt;
&lt;pre class="brush:csharp"&gt;public class RoleProviderDecorator&amp;lt;TSurrogateRoleProvider&amp;gt; : RoleProvider
        where TSurrogateRoleProvider : RoleProvider, new()
    {

        protected TSurrogateRoleProvider _surrogate;

        public override void Initialize(string name, NameValueCollection config)
        {
            if (config == null)
                throw new ArgumentNullException(&amp;quot;config&amp;quot;);

            base.Initialize(name, config);

            _surrogate = new TSurrogateRoleProvider();

            InitializeInnerProvider(_surrogate, name, config);
        }

        protected virtual void InitializeInnerProvider(RoleProvider innerProvider, string name, NameValueCollection config)
        {
            innerProvider.Initialize(name, config);
        }
        
        public override bool IsUserInRole(string username, string roleName)
        {
            return _surrogate.IsUserInRole(username, roleName);
        }
        
        public override string[] GetRolesForUser(string username)
        {
            return _surrogate.GetRolesForUser(username).ToArray();
        }
        
        public override void CreateRole(string roleName)
        {
            _surrogate.CreateRole(roleName);
        }
        
        public override bool DeleteRole(string roleName, bool throwOnPopulatedRole)
        {
            return _surrogate.DeleteRole(roleName, throwOnPopulatedRole);
        }
        
        public override bool RoleExists(string roleName)
        {
            return _surrogate.RoleExists(roleName);
        }
        
        public override void AddUsersToRoles(string[] usernames, string[] roleNames)
        {
            _surrogate.AddUsersToRoles(usernames, roleNames);
        }
        
        public override void RemoveUsersFromRoles(string[] usernames, string[] roleNames)
        {
            _surrogate.RemoveUsersFromRoles(usernames, roleNames);
        }
        
        public override string[] GetUsersInRole(string roleName)
        {
            return _surrogate.GetUsersInRole(roleName).ToArray();
        }
        
        public override string[] GetAllRoles()
        {
            return _surrogate.GetAllRoles().ToArray();
        }
        
        public override string[] FindUsersInRole(string roleName, string usernameToMatch)
        {
            return
                _surrogate.FindUsersInRole(roleName, usernameToMatch).ToArray();
        }
        
        public override string ApplicationName
        {
            get { return _surrogate.ApplicationName; }
            set { _surrogate.ApplicationName = value; }
        }
    }
&lt;/pre&gt;&lt;br /&gt;
L'idée du décorateur, vous l'aurez compris, est de déléguer l’exécution des méthodes au vrai RoleProvider passé sous forme de &lt;a href="http://msdn.microsoft.com/en-us/library/ms379564%28v=vs.80%29.aspx"&gt;Generic&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
Maintenant définissons un RoleProvider qui se charge d'utiliser de manière sous-jacente deux RoleProvider :&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush:csharp"&gt;public abstract class UnionRoleProvider&amp;lt;TPrimaryRoleProvider, TSecondaryRoleProvider&amp;gt; : RoleProviderDecorator&amp;lt;TPrimaryRoleProvider&amp;gt;
        where TPrimaryRoleProvider : RoleProvider, new()
        where TSecondaryRoleProvider : RoleProvider, new()
    {
        private TSecondaryRoleProvider _secondSurrogate;

        public override void Initialize(string name, NameValueCollection config)
        {
            if (config == null)
                throw new ArgumentNullException(&amp;quot;config&amp;quot;);

            base.Initialize(name, config);

            _secondSurrogate = new TSecondaryRoleProvider();
            InitializeInnerProvider(_secondSurrogate, name, config);
        }

        public override bool IsUserInRole(string username, string roleName)
        {
            return _surrogate.IsUserInRole(username, roleName) || _secondSurrogate.IsUserInRole(username, roleName);
        }

        public override string[] GetRolesForUser(string username)
        {
            return _surrogate.GetRolesForUser(username).Union(_secondSurrogate.GetRolesForUser(username)).ToArray();
        }

        public override void CreateRole(string roleName)
        {
            _surrogate.CreateRole(roleName);
            _secondSurrogate.CreateRole(roleName);
        }

        public override bool DeleteRole(string roleName, bool throwOnPopulatedRole)
        {
            return _surrogate.DeleteRole(roleName, throwOnPopulatedRole) &amp;amp;&amp;amp; _surrogate.DeleteRole(roleName, throwOnPopulatedRole);
        }

        public override bool RoleExists(string roleName)
        {
            return _surrogate.RoleExists(roleName) || _secondSurrogate.RoleExists(roleName);
        }

        public override void AddUsersToRoles(string[] usernames, string[] roleNames)
        {
            _surrogate.AddUsersToRoles(usernames, roleNames);
            _secondSurrogate.AddUsersToRoles(usernames, roleNames);
        }

        public override void RemoveUsersFromRoles(string[] usernames, string[] roleNames)
        {
            _surrogate.RemoveUsersFromRoles(usernames, roleNames);
            _secondSurrogate.RemoveUsersFromRoles(usernames, roleNames);
        }

        public override string[] GetUsersInRole(string roleName)
        {
            return _surrogate.GetUsersInRole(roleName).Union(_secondSurrogate.GetUsersInRole(roleName)).ToArray();
        }

        public override string[] GetAllRoles()
        {
            return _surrogate.GetAllRoles().Union(_secondSurrogate.GetAllRoles()).ToArray();
        }

        public override string[] FindUsersInRole(string roleName, string usernameToMatch)
        {
            return
                _surrogate.FindUsersInRole(roleName, usernameToMatch)
                    .Union(_secondSurrogate.FindUsersInRole(roleName, usernameToMatch))
                    .ToArray();
        }
    }
&lt;/pre&gt;&lt;br /&gt;
Dans mon cas, seul un des deux RoleProvider doit pouvoir écrire dans son médium de stockage. &lt;br /&gt;
L'autre doit être en lecture seule. Pour ce faire, j'introduis un ReadOnlyRoleProvider : &lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush:csharp"&gt;public class ReadOnlyRoleProvider&amp;lt;TSurrogateRoleProvider&amp;gt; : RoleProviderDecorator&amp;lt;TSurrogateRoleProvider&amp;gt;
        where TSurrogateRoleProvider : RoleProvider, new()
    {

        public override void CreateRole(string roleName){}

        public override bool DeleteRole(string roleName, bool throwOnPopulatedRole)
        {
            return true;
        }

        public override void AddUsersToRoles(string[] usernames, string[] roleNames){}

        public override void RemoveUsersFromRoles(string[] usernames, string[] roleNames){}
&lt;/pre&gt;&lt;br /&gt;
Ça y est on a fait 90% du boulot.&lt;br /&gt;
&lt;br /&gt;
Dans le fichier web.config on veut écrire ceci : &lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush:xml"&gt;&amp;lt;roleManager enabled=&amp;quot;true&amp;quot; defaultProvider=&amp;quot;MyRoleProvider&amp;quot;&amp;gt;
      &amp;lt;providers&amp;gt;
        &amp;lt;clear/&amp;gt;
        &amp;lt;add name=&amp;quot;MyRoleProvider &amp;quot; type=&amp;quot;Providers.MyRoleProvider &amp;quot; connectionStringName=&amp;quot;cnx&amp;quot; applicationName=&amp;quot;MyApp&amp;quot; /&amp;gt;
      &amp;lt;/providers&amp;gt;
    &amp;lt;/roleManager&amp;gt;
&lt;/pre&gt;&lt;br /&gt;
Étant donné que l'on ne peut pas utiliser de classe générique dans la config, on va simplement en spécialiser une :&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush:csharp"&gt;public class MyRoleProvider : UnionRoleProvider&amp;lt;SqlRoleProvider, SilentWindowsTokenRoleProvider&amp;lt;WindowsTokenRoleProvider&amp;gt;&amp;gt;
    {

        protected override void InitializeInnerProvider(RoleProvider innerProvider, string name, NameValueCollection config)
        {
            NameValueCollection cfg = config;
            if (innerProvider is ReadOnlyRoleProvider&amp;lt;WindowsTokenRoleProvider&amp;gt;)
            {
                cfg = new NameValueCollection(config);
                cfg.Remove(&amp;quot;connectionStringName&amp;quot;);
            }
            
            base.InitializeInnerProvider(innerProvider, name, cfg);
        }
    }
&lt;/pre&gt;&lt;br /&gt;
Ouf, 99% du boulot. Vous pouvez maintenant exécuter et ça va fonctionner... jusqu'à ce que vous utilisiez une des méthodes suivantes : &lt;br /&gt;
&lt;ul&gt;&lt;li&gt;GetUsersInRole&lt;/li&gt;
&lt;li&gt;GetAllRoles&lt;/li&gt;
&lt;li&gt;FindUsersInRole&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
Tout simplement parce que le  &lt;a href="http://msdn.microsoft.com/fr-fr/library/system.web.security.windowstokenroleprovider.aspx"&gt;WindowsTokenRoleProvider&lt;/a&gt; ne supporte pas ces opérations.&lt;br /&gt;
Ok, voici le tout dernier % à réaliser : &lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush:csharp"&gt;public class SilentWindowsTokenRoleProvider&amp;lt;TSurrogateRoleProvider&amp;gt; : ReadOnlyRoleProvider&amp;lt;TSurrogateRoleProvider&amp;gt;
        where TSurrogateRoleProvider : RoleProvider, new()
    {

        public override string[] GetUsersInRole(string roleName)
        {
            return new string[]{};
        }

        public override string[] GetAllRoles()
        {
            return new string[]{};
        }

        public override string[] FindUsersInRole(string roleName, string usernameToMatch)
        {
            return new string[]{};
        }
    }
&lt;/pre&gt;&lt;br /&gt;
Voila 100% de la solution; beaucoup de code aujourd'hui, j'espère que ça ne vous a pas trop démotivé.&lt;br /&gt;
&lt;br /&gt;
Si vous avez une solution autre, ou contestez mon approche n'hésitez pas à laisser un commentaire.&lt;br /&gt;
&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1146316188254265608-4921929042336737796?l=mymemoryleaks.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mymemoryleaks.blogspot.com/feeds/4921929042336737796/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1146316188254265608&amp;postID=4921929042336737796' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1146316188254265608/posts/default/4921929042336737796'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1146316188254265608/posts/default/4921929042336737796'/><link rel='alternate' type='text/html' href='http://mymemoryleaks.blogspot.com/2011/10/implementer-une-securite-base-de-roles.html' title='Implémenter une sécurité à base de rôles avec Windows Authentication &amp; SQL Server'/><author><name>Fabrice Michellonet</name><uri>http://www.blogger.com/profile/10201820062243684793</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_yYUu3sWKdtU/SE76j2im4AI/AAAAAAAACFA/OgO15yojzu8/S220/Fabrice_MICHELLONET.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1146316188254265608.post-5058619291898102502</id><published>2011-10-07T16:55:00.001+02:00</published><updated>2011-10-17T15:57:45.962+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Afterthought'/><category scheme='http://www.blogger.com/atom/ns#' term='EntityFramework.Patterns'/><category scheme='http://www.blogger.com/atom/ns#' term='Entity Framework'/><category scheme='http://www.blogger.com/atom/ns#' term='AOP'/><title type='text'>Entity Framework et AOP</title><content type='html'>&lt;p&gt;Cela fait des mois que je repousse la publication d'un post sur l'&lt;a href="http://en.wikipedia.org/wiki/Aspect-oriented_programming"&gt;AOP&lt;/a&gt;, car je ne voulais pas vous resservir le sempiternel exemple de mise en place d'une gestion de log applicatif simplifiée. &lt;br /&gt;
Si vous voulez vous rafraichir les idées sur le sujet je vous conseille de jeter un œil sur l'article d'&lt;a href="http://ayende.com/blog/3474/logging-the-aop-way"&gt;Ayende Rahien sur le sujet&lt;/a&gt;&lt;br /&gt;
&lt;/p&gt;Avec le framework .NET, il existe au moins 6 façons différentes d'ajouter un brin d'AOP dans vos programmes; &lt;br /&gt;
Pour mémoire il s'agit de : &lt;br /&gt;
&lt;ul&gt;&lt;li&gt;Remoting Proxies&lt;/li&gt;
&lt;li&gt;Dériver votre classe de ContextBoundObject&lt;/li&gt;
&lt;li&gt;Passer par un dynamique proxy ( ex : Castle Dynamic Proxy)&lt;/li&gt;
&lt;li&gt;Utiliser l'API de profiling de .NET&lt;/li&gt;
&lt;li&gt;Injection d'IL après compilation&lt;/li&gt;
&lt;li&gt;Injection d'IL au runtime&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
Dans cet article on s'intéressera particulièrement a l'injection post compilation, tout simplement car c'est la plus performante (le code lié à l'aspect est directement inscrit dans l'assembly finale et rien ne le distingue du reste du code) et aussi car c'est la façon la plus sexy a mon gout de faire de l'AOP (c'est une raison comme une autre, non?).&lt;br /&gt;
&lt;br /&gt;
Bon revenons à nos moutons.&lt;br /&gt;
&lt;br /&gt;
Sur presque tous les projets sur lesquels je suis intervenu ces dernières années, lorsqu'on modélise les entités qui devront être persistées en base, on leur adjoint au moins quatre propriétés :&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;Created By (string)&lt;/li&gt;
&lt;li&gt;Created (datetime)&lt;/li&gt;
&lt;li&gt;Last Updated By (string)&lt;/li&gt;
&lt;li&gt;Last Updated (datetime)&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
J'ai pour habitude de nommer cette construction, une entité "Auditable", ce qui se traduit en code par l'interface suivante : &lt;br /&gt;
&lt;pre class="brush:csharp"&gt;public interface IAuditable
    {
        string CreatedBy { get; set; }
        DateTime Created { get; set; }
        string UpdatedBy { get; set; }
        DateTime? Updated { get; set; }
    }
&lt;/pre&gt;&lt;br /&gt;
Vous l'aurez compris, l'idée ici, est de stocker la date et l'utilisateur ayant créé ou modifié l'entité en question et ceci a chaque accès base. &lt;br /&gt;
Je vous laisse imaginer le travail rébarbatif que cela peut vite devenir si l'on doit tout gérer à la main et si notre modèle est composé de dizaines voire de centaines d'entités.&lt;br /&gt;
&lt;br /&gt;
Je vous propose donc une idée afin de se faciliter la vie grâce à l'AOP. &lt;br /&gt;
Il est à noter que bien que l'exemple ci-dessous s’appuie sur Entity Framework, le mécanisme est très certainement transposable (avec adaptation) aux autres ORM.&lt;br /&gt;
&lt;br /&gt;
On commence par utiliser Entity Framework Code First, et on ajoute notre framework AOP préféré&lt;br /&gt;
&lt;pre class="brush:powershell"&gt;Install-Package EntityFramework
Install-Package Afterthought
&lt;/pre&gt;&lt;br /&gt;
&lt;blockquote&gt;En attendant qu'un de mes patch soit accepté et intégré à &lt;a href="https://github.com/vc3/Afterthought"&gt;Afterthought&lt;/a&gt;, il vous faudra remplacer la dll d'Afterthought par la mienne disponible &lt;a href="http://fabrice.michellonet.free.fr/MyMemoryLeaks/Posts/44/afterthought.zip"&gt;ici&lt;/a&gt;.&lt;br /&gt;
&lt;/blockquote&gt;&lt;br /&gt;
Nuget a rajouté quelques dll et références dans votre projet et modifié également le post build event de votre projet; &lt;br /&gt;
Désormais à chaque compilation, Afterthought scannera les assemblies à la recherche de taches d'injection d'IL à effectuer.&lt;br /&gt;
&lt;br /&gt;
Voyons comment demander à Afterthought d'injecter l'interface IAuditable sur nos entités.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush:csharp"&gt;public class AuditableAmender&amp;lt;T&amp;gt; : Amendment&amp;lt;T, T&amp;gt;
    {

        public AuditableAmender()
        {
            Properties.Add&amp;lt;string&amp;gt;(&amp;quot;CreatedBy&amp;quot;);
            Properties.Add&amp;lt;DateTime&amp;gt;(&amp;quot;Created&amp;quot;);
            Properties.Add&amp;lt;string&amp;gt;(&amp;quot;UpdatedBy&amp;quot;);
            Properties.Add&amp;lt;DateTime?&amp;gt;(&amp;quot;Updated&amp;quot;);

            Implement&amp;lt;IAuditable&amp;gt;();
        }
    }
&lt;/pre&gt;&lt;br /&gt;
Le code me semble assez clair sans avoir a revenir longuement dessus; On demande simplement à Afterthought d'injecter les propriétés nécessaires à l'implémentation de l'interface IAuditable.&lt;br /&gt;
&lt;br /&gt;
Bien créons un attribut de marquage, que nous placerons sur nos entités :&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush:csharp"&gt;[AttributeUsage(AttributeTargets.Class)]
    public class AuditableAttribute : Attribute { }
&lt;/pre&gt;&lt;br /&gt;
il nous reste encore deux tâches à réaliser; &lt;br /&gt;
&lt;ul&gt;&lt;li&gt;Préciser les assemblies à introspecter&lt;/li&gt;
&lt;li&gt;Permettre à Afterthought de découvrir les classes qui doivent être modifiées et surtout comment.&lt;/li&gt;
&lt;/ul&gt;Cela se fait dans une même classe : &lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush:csharp"&gt;[AttributeUsage(AttributeTargets.Assembly)]
    public class AmendAttribute : Attribute, IAmendmentAttribute
    {
        IEnumerable&amp;lt;ITypeAmendment&amp;gt; IAmendmentAttribute.GetAmendments(Type target)
        {
            if (target.GetCustomAttributes(typeof(AuditableAttribute), true).Length &amp;gt; 0)
            {
                ConstructorInfo constructorInfo = typeof(AuditableAmender&amp;lt;&amp;gt;).MakeGenericType(target).GetConstructor(Type.EmptyTypes);
                if (constructorInfo != null)
                    yield return (ITypeAmendment)constructorInfo.Invoke(new object[0]);
            }
        }
    }
&lt;/pre&gt;En clair, pour chaque classe qui implémente IAuditable, on va faire appel à la classe AuditableAmender (créée précédemment) pour modifier la classe.&lt;br /&gt;
En appliquant cet attribut sur l'assembly qui contient vos entités, Afterthought effectuera son travail d'injection.&lt;br /&gt;
&lt;br /&gt;
Désormais si l'on applique l'attribut Auditable sur une de nos entités comme suit :&lt;br /&gt;
&lt;pre class="brush:csharp"&gt;[Auditable]
    public class Product
    {
        public int Id { get; set; }
        public string Name { get; set; }
    }

    public class Context : DbContext
    {
        public virtual DbSet&amp;lt;Product&amp;gt; Products { get; set; }

        public Context()
        {
            Database.SetInitializer(new DropCreateDatabaseIfModelChanges&amp;lt;Context&amp;gt;());
        }
    }
&lt;/pre&gt;&lt;br /&gt;
Ce qui produit bien en base la table suivante : &lt;br /&gt;
&lt;br /&gt;
&lt;img src="http://fabrice.michellonet.free.fr/MyMemoryLeaks/Posts/44/EF_Table.png" alt="table"/&gt;&lt;br /&gt;
&lt;br /&gt;
et dans l'assembly finale (vu avec Reflector)&lt;br /&gt;
&lt;br /&gt;
&lt;img src="http://fabrice.michellonet.free.fr/MyMemoryLeaks/Posts/44/Asm.png" alt="assembly"/&gt;&lt;br /&gt;
&lt;br /&gt;
Évidemment, en généralisant ce principe il est possible de facilement faire évoluer votre modèle sans avoir à travailler parfois de manière répétitive.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Vous retrouverez cette fonctionnalité (il vous suffit de marquer votre entité avec l'attribut) dans la librairie &lt;a href="http://efpatterns.codeplex.com/"&gt;EntityFramework.Patterns&lt;/a&gt; que je maintiens et disponible via &lt;a href="http://nuget.org/List/Packages/EntityFramework.Patterns"&gt;nuget&lt;/a&gt;.&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Que pensez-vous de cette technique?&lt;br /&gt;
Utilisez-vous un autre framework (&lt;a href="http://www.sharpcrafters.com/"&gt;Postsharp&lt;/a&gt;) pour réaliser ce genre de tâche?&lt;br /&gt;
&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1146316188254265608-5058619291898102502?l=mymemoryleaks.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mymemoryleaks.blogspot.com/feeds/5058619291898102502/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1146316188254265608&amp;postID=5058619291898102502' title='4 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1146316188254265608/posts/default/5058619291898102502'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1146316188254265608/posts/default/5058619291898102502'/><link rel='alternate' type='text/html' href='http://mymemoryleaks.blogspot.com/2011/10/entity-framework-et-aop.html' title='Entity Framework et AOP'/><author><name>Fabrice Michellonet</name><uri>http://www.blogger.com/profile/10201820062243684793</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_yYUu3sWKdtU/SE76j2im4AI/AAAAAAAACFA/OgO15yojzu8/S220/Fabrice_MICHELLONET.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1146316188254265608.post-7833601605957993703</id><published>2011-09-26T23:21:00.000+02:00</published><updated>2011-09-26T23:21:31.607+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='ASP.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='ASP.NET MVC'/><category scheme='http://www.blogger.com/atom/ns#' term='SignalR'/><title type='text'>Live charting avec SignalR</title><content type='html'>&lt;p&gt;&lt;a href="https://github.com/SignalR"&gt;SignalR&lt;/a&gt; is awesome ! Oui il va falloir vous habituer à entendre dire que cette librairie est un petit bijou.&lt;/p&gt;&lt;br /&gt;
&lt;img alt="tweet signalr" src="http://fabrice.michellonet.free.fr/MyMemoryLeaks/Posts/43/SignalR_awesome.png" /&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;p&gt;&lt;b&gt;Mais qu'est-ce qu'elle a de si bien cette librairie SignalR ?&lt;/b&gt;&lt;/p&gt;SignalR fournit une couche d'abstraction au-dessus des &lt;a href="http://en.wikipedia.org/wiki/WebSocket"&gt;WebSocket&lt;/a&gt; et des &lt;a href="http://en.wikipedia.org/wiki/Long_polling#Long_polling"&gt;long polling connections&lt;/a&gt; pour les développeurs .NET et fonctionne sous IIS sans avoir à installer un autre service à côté.&lt;br /&gt;
&lt;br /&gt;
Jusqu'alors il existait bien des solutions commerciales de ces technos dans l'écosystème .NET mais aucune n'avait vraiment convaincu, souvent par manque d'intégration forte entre le client et le serveur; rendant la communication entre les deux fastidieuse.&lt;br /&gt;
Avec SignalR c'est tout le contraire, le code serveur et le code client ne semble faire qu'un. Les lignes de code glissent du serveur vers le navigateur, sans aucune lourdeur. C'est &lt;b&gt;SIMPLE&lt;/b&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Comme d'hab, rien de mieux qu'un petit bout de code pour démontrer ça.&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Bon, si vous avez lu le titre vous avez une petite idée de ce que l'on va coder...&lt;br /&gt;
&lt;br /&gt;
Coté composants techniques, évidement SignalR pour la communication client/serveur et &lt;a href="http://www.highcharts.com/"&gt;Highchart&lt;/a&gt; coté client pour dessiner le chart.&lt;br /&gt;
&lt;br /&gt;
Après avoir créé un nouveau projet WebForm ou MVC ajoutez le package SignalR via &lt;a href="http://nuget.org/"&gt;nuget&lt;/a&gt;.&lt;br /&gt;
Intéressons-nous au code javascript. (&lt;i&gt;A noter que le code lié à la configuration du chart à été omis a des fins de clarté.&lt;/i&gt;)&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush:js"&gt;$(function () {
     var stockExchangeServer = $.connection.stockExchange;

    stockExchangeServer.drawShareValue = function (id, content) {

        if (id != this.Id) {
            return;
        }

        // set up the updating of the chart.
        var series = chart.series[0];
        var x = new Date(parseInt(content[0].Date.substr(6))).getTime(),
                y = content[0].Price;

        series.addPoint([x, y], true, true);
    };

    $.connection.hub.start(function () {
        stockExchangeServer.connect();
            .done(function (success) {
                if (success === false) {
                    console.log(":(");
                }
                console.log("connected");
            });
    });
});
&lt;/pre&gt;&lt;br /&gt;
Pour initier la communication avec le serveur, il suffit comme vous pouvez le voir d'utiliser la méthode &lt;code&gt;$.connection.hub.start()&lt;/code&gt;; &lt;br /&gt;
On se contente alors de faire appel à la méthode &lt;code&gt;connect&lt;/code&gt;; nous implémenterons cette dernière côté serveur.... oui vous avez bien lu, côté serveur.&lt;br /&gt;
&lt;br /&gt;
Remarquez également la définition de la méthode &lt;code&gt;drawShareValue()&lt;/code&gt; qui se charge de dessiner un nouveau point dans le chart, nous ferons appel à elle dans le code serveur.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Côté serveur, nous allons définir un hub, la classe de base qui abstrait la communication client/serveur dans l'api SignalR.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush:csharp"&gt;public class StockExchange : Hub
    {
        private Timer _timer;

        private double _fowlerPrice = 10.2;

        private double VaryPrice()
        {
            Random rnd = new Random();
            _fowlerPrice = _fowlerPrice + (rnd.Next(-1, 2) * rnd.NextDouble());
            return _fowlerPrice;
        }

        public bool Connect()
        {
            // Set unique id for client.
            Caller.Id = Context.ClientId;

            _timer = new Timer { Interval = 1000 };

            _timer.Elapsed += (sender, e) =&amp;gt; Send(
                new List&amp;lt;SharePrice&amp;gt;(new[]
                                         {
                                             new SharePrice
                                                 {
                                                     Date = DateTime.Now,
                                                     Price = VaryPrice(),
                                                     Share = new Share {Name = "Fowler-Corp"}
                                                 }
                                         }));
            _timer.Start();

            return true;
        }

        public void Send(IEnumerable&amp;lt;SharePrice&amp;gt; sp)
        {
            Clients.drawShareValue(Context.ClientId, sp);
        }
    }
&lt;/pre&gt;&lt;br /&gt;
Avez-vous remarqué la méthode Connect()? On y a fait appel à partir du code JS.&lt;br /&gt;
Et l'appel à drawShareValue(), fait bien référence à la méthode que l'on à définit dans le javascript. Enorme, non?&lt;br /&gt;
&lt;br /&gt;
Tout cela est possible parce que SignalR utilise dans ses fondements le typage &lt;a href="http://en.wikipedia.org/wiki/C_Sharp_4.0#Dynamic_member_lookup"&gt;dynamic&lt;/a&gt; à laquelle vient s'ajouter une résolution de Propriété/Méthode "simple" par convention, évitant ainsi d'avoir à écrire du code verbeux.&lt;br /&gt;
&lt;br /&gt;
Au final, voici ce que l'on peut obtenir...&lt;br /&gt;
&lt;br /&gt;
&lt;img src="http://fabrice.michellonet.free.fr/MyMemoryLeaks/Posts/43/chart_crop.png" alt="chart"/&gt;&lt;br /&gt;
&lt;br /&gt;
Bon ok, l'image ne bouge pas, il faut imaginer qu'un point vient s'ajouter chaque seconde dans le graph :)&lt;br /&gt;
&lt;br /&gt;
Pour ceux qui voudrait jeter un coup d’œil à la solution entière, vous pouvez la récupérer sur &lt;a href="https://github.com/fmichellonet/SignalR.Samples.MVCLiveChart"&gt;Github&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Avez-vous utilisé d'autres technos/framework pour faciliter les communications "temps réel" entre le serveur et le browser?&lt;br/&gt;&lt;br /&gt;
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1146316188254265608-7833601605957993703?l=mymemoryleaks.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mymemoryleaks.blogspot.com/feeds/7833601605957993703/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1146316188254265608&amp;postID=7833601605957993703' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1146316188254265608/posts/default/7833601605957993703'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1146316188254265608/posts/default/7833601605957993703'/><link rel='alternate' type='text/html' href='http://mymemoryleaks.blogspot.com/2011/09/live-charting-avec-signalr.html' title='Live charting avec SignalR'/><author><name>Fabrice Michellonet</name><uri>http://www.blogger.com/profile/10201820062243684793</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_yYUu3sWKdtU/SE76j2im4AI/AAAAAAAACFA/OgO15yojzu8/S220/Fabrice_MICHELLONET.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1146316188254265608.post-3820879386763448703</id><published>2011-07-13T17:07:00.002+02:00</published><updated>2011-07-13T17:12:03.051+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='EntityFramework.Patterns'/><category scheme='http://www.blogger.com/atom/ns#' term='ORM'/><title type='text'>EntityFramework.Patterns : Repository &amp; Unit Of Work</title><content type='html'>&lt;p&gt;
Je vous propose un très rapide post pour faciliter la prise en main des Patterns Repository&lt;T&gt; et Unit Of Work disponibles dans &lt;a href=""&gt;EntityFramework.Patterns&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;Pour simplifier le sujet, le but du pattern Repository est de donner au développeur une passerelle de requêtage unifiée, via des opérations (le plus souvent) atomiques.
Unit Of Work, est la quant à lui pour valider transactionnellement un ensemble de modifications faites sur les données.&lt;/p&gt;
&lt;p&gt;Pour la version longue vous pourrez trouver votre bonheur sur le site de &lt;a href="http://martinfowler.com/"&gt;Martin Fowler&lt;/a&gt; &lt;a href="http://martinfowler.com/eaaCatalog/repository.html"&gt;ici pour le Repository&lt;/a&gt; et &lt;a href="http://martinfowler.com/eaaCatalog/unitOfWork.html"&gt;ici pour Unit Of Work&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;Partons d'un modèle simplissime comme celui ci-dessous :
&lt;pre class="brush:csharp"&gt;

public class Context : DbContext
{
    public virtual DbSet&amp;lt;Product&amp;gt; Products { get; set; }
    public virtual DbSet&amp;lt;ProductCategory&amp;gt; Categories { get; set; }

    public Context()
    {
        Database.SetInitializer(new DropCreateDatabaseAlways&amp;lt;Context&amp;gt;());
    }
}

public class Product
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int? ProductCategoryId { get; set; }
    public virtual ProductCategory ProductCategory { get; set; }
}

public class ProductCategory
{
    public int Id { get; set; }
    public string Name { get; set; }
}
&lt;/pre&gt;
&lt;/p&gt;
&lt;p&gt;Commençons par créer le Repository
&lt;pre class="brush:csharp"&gt;
using(Context ctx = new Context())
{
    DbContextAdapter adapter = new DbContextAdapter(ctx);
    IRepository&amp;lt;Product&amp;gt; productRepo = new Repository&amp;lt;Product&amp;gt;(adp);
    ...
}
&lt;/pre&gt;
&lt;/p&gt;
&lt;p&gt;Interrogeons la base pour ramener l'ensemble des produits :
&lt;pre class="brush:csharp"&gt;
IEnumerable&amp;lt;Product&amp;gt; lst = productRepo.GetAll();
&lt;/pre&gt;
&lt;/p&gt;
&lt;p&gt;Ramenons le premier élément dont le nom commence par "Bike"&lt;/p&gt;
&lt;pre class="brush:csharp"&gt;
Product prod = productRepo.First(p =&amp;gt; p.Name.StartsWith(&amp;quot;Bike&amp;quot;));
&lt;/pre&gt;
&lt;p&gt;L'utilisation de la méthode Single a pour effet de ramener un seul élément de la base de données; mais lève une exception si plusieurs éléments répondent aux critères demandés.
&lt;pre class="brush:csharp"&gt;
 productRepo.Single(p =&amp;gt; p.Name.StartsWith(&amp;quot;Roc&amp;quot;))
&lt;/pre&gt;
&lt;/p&gt;
&lt;p&gt;Find(), permet de filtrer en fonction de plusieurs critères :
&lt;pre class="brush:csharp"&gt;
IEnumerable&amp;lt;Product&amp;gt; lst = productRepo.Find(
                p =&amp;gt; p.Id &amp;lt; 100 &amp;amp;&amp;amp; p.Name.Contains(&amp;quot;o&amp;quot;) &amp;amp;&amp;amp; p.Name.Length &amp;lt; 20);
&lt;/pre&gt;
&lt;/p&gt;
&lt;p&gt;Toutes ces méthodes acceptent optionnellement un ensemble de liens de navigation inter entités 
&lt;pre class="brush:csharp"&gt;params Expression&amp;lt;Func&amp;lt;T, object&amp;gt;&amp;gt;[] includeProperties&lt;/pre&gt;
définissant les jointures à effectuer lors du requêtage.
Ainsi :
&lt;pre class="brush:csharp"&gt;
productRepo.First(p =&amp;gt; p.ProductCategoryId != null , p =&amp;gt; p.ProductCategory);
&lt;/pre&gt;
charge le produit et sa catégorie associée en une seule requete SQL; Cette façon de faire nous protège du fameux problème du &lt;a href="http://stackoverflow.com/questions/97197/what-is-the-n1-selects-problem"&gt;Select N+1&lt;/a&gt; lié au &lt;a href="http://en.wikipedia.org/wiki/Lazy_loading"&gt;lazy loading&lt;/a&gt; utilisé par défaut avec Entity Framework.
&lt;/p&gt;
&lt;p&gt;Après l’interrogation de la base passons a la persistance de nos données. Pour cela nous allons faire appel au pattern UnitOfWork.
L'insertion d'un nouvel élément prend cette forme :
&lt;pre class="brush:csharp"&gt;
using(...)
{
   ...
   IUnitOfWork unitOfWork = new UnitOfWork(adp);
   Product p = new Product{Name = "Skateboard"};
   productRepo.Insert(p);
   unitOfWork.Commit();
}
&lt;/pre&gt;
&lt;/p&gt;
&lt;p&gt;Vous l'aurez compris la mise à jour et la suppression sont aussi simple que ca : 
&lt;pre class="brush:csharp"&gt;
Product p = productRepo.First(c =&amp;gt; c.Name == &amp;quot;Bike&amp;quot;);
p.Name = "New bike";
productRepo.Update(p);

Product delete = productRepo.First(p =&amp;gt; p.Name.StartsWith(&amp;quot;To be&amp;quot;)); 
productRepo.Delete(delete);

unitOfWork.Commit();
&lt;/pre&gt;
&lt;/p&gt;
&lt;p&gt;Dans les prochains jours je vous montrerais comment injecter Repository et Unit of work dans une couche Service par exemple avec un conteneur DI comme &lt;a href="http://ninject.org/"&gt;NInject&lt;/a&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1146316188254265608-3820879386763448703?l=mymemoryleaks.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mymemoryleaks.blogspot.com/feeds/3820879386763448703/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1146316188254265608&amp;postID=3820879386763448703' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1146316188254265608/posts/default/3820879386763448703'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1146316188254265608/posts/default/3820879386763448703'/><link rel='alternate' type='text/html' href='http://mymemoryleaks.blogspot.com/2011/07/entityframeworkpatterns-repository-unit_13.html' title='EntityFramework.Patterns : Repository &amp; Unit Of Work'/><author><name>Fabrice Michellonet</name><uri>http://www.blogger.com/profile/10201820062243684793</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_yYUu3sWKdtU/SE76j2im4AI/AAAAAAAACFA/OgO15yojzu8/S220/Fabrice_MICHELLONET.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1146316188254265608.post-7405101182765635229</id><published>2011-07-07T18:32:00.001+02:00</published><updated>2011-07-07T18:39:26.839+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='EntityFramework.Patterns'/><title type='text'>Release d'EntityFramework.Patterns</title><content type='html'>&lt;p&gt;Bon ça y est je me suis décidé à trouver un toit pour &lt;a href="http://efpatterns.codeplex.com/"&gt;EntityFramework.Patterns&lt;/a&gt;, une librairie qui s'adossant à &lt;a href="http://msdn.microsoft.com/en-us/data/aa937723"&gt;Entity Framework 4.1&lt;/a&gt;, propose l'implémentation de patterns couramment nécessaire lorsqu'on utilise un &lt;a href="http://en.wikipedia.org/wiki/Object-relational_mapping"&gt;ORM&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
Je n'ai toujours pas cédé aux appels des sirènes de &lt;a href="https://github.com/"&gt;Github&lt;/a&gt;; EntityFramework.Patterns est donc hébergé sur &lt;a href="http://www.codeplex.com/"&gt;Codeplex&lt;/a&gt;.
Vous trouverez également la librairie sur &lt;a href="http://nuget.org/List/Search?packageType=Packages&amp;searchCategory=All+Categories&amp;searchTerm=EntityFramework.Patterns&amp;sortOrder=package-download-count&amp;pageSize=10"&gt;nuget&lt;/a&gt;... d'ailleurs elle y était présente bien avant la création du repository sur codeplex.
&lt;/p&gt;
&lt;p&gt;
Pour l'installer via nuget, rien de plus simple :
&lt;pre class="brush: ps"&gt;
install-package EntityFramework.Patterns
&lt;/pre&gt;
&lt;/p&gt;
&lt;p&gt;
A l'heure actuelle, vous trouverez deux patterns d'infrastructure :
&lt;ul&gt;
&lt;li&gt;Repository&lt;/li&gt;
&lt;li&gt;Unit Of work&lt;/li&gt;
&lt;/ul&gt;

&lt;a href="http://wekeroad.com/post/7102729511/a-simple-example-thats-incredibly-complex"&gt;Rob Conery&lt;/a&gt; les définissaient ainsi récemment : 

&lt;blockquote&gt;
The Repository Pattern is all about encapsulating calls to your DB as methods to do a thing. These calls are (typically) atomic.
&lt;/blockquote&gt;
&lt;br/&gt;
Tout est dit! L'avantage est simple, couplé avec &lt;a href="http://blog.ploeh.dk/2010/09/20/InstrumentationWithDecoratorsAndInterceptors.aspx"&gt;un/des décorateurs&lt;/a&gt; il sera facile d'ajouter des comportements transverses (cache, securité, log etc...)

&lt;blockquote&gt;
UnitOfWork is - well it’s a way of transactionally flushing changes to a persistence store (aka Database)
&lt;/blockquote&gt;
&lt;br/&gt;
Ce qui permet de découpler facilement la gestion d'état des entités et le requêtage.
&lt;/p&gt;

&lt;p&gt;Des patterns d'infrastructure pour l'instant, qui seront rapidement suivit par les patterns suivants :
&lt;ul&gt;
&lt;li&gt;Repository Decorator&lt;/li&gt;
&lt;li&gt;Audit log&lt;/li&gt;
&lt;li&gt;Audit trail&lt;/li&gt;
&lt;li&gt;Archived entity&lt;/li&gt;
&lt;li&gt;Internationalized entity&lt;/li&gt;
&lt;/ul&gt;
&lt;/p&gt;

&lt;p&gt;
Dans un tout prochain post je présenterais ces deux patterns Repostitory&amp;lt;T&amp;gt; et UnitOfWork.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1146316188254265608-7405101182765635229?l=mymemoryleaks.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mymemoryleaks.blogspot.com/feeds/7405101182765635229/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1146316188254265608&amp;postID=7405101182765635229' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1146316188254265608/posts/default/7405101182765635229'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1146316188254265608/posts/default/7405101182765635229'/><link rel='alternate' type='text/html' href='http://mymemoryleaks.blogspot.com/2011/07/release-dentityframeworkpatterns.html' title='Release d&apos;EntityFramework.Patterns'/><author><name>Fabrice Michellonet</name><uri>http://www.blogger.com/profile/10201820062243684793</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_yYUu3sWKdtU/SE76j2im4AI/AAAAAAAACFA/OgO15yojzu8/S220/Fabrice_MICHELLONET.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1146316188254265608.post-535820351817854973</id><published>2011-07-07T16:51:00.000+02:00</published><updated>2011-07-07T16:51:38.029+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Electronique'/><category scheme='http://www.blogger.com/atom/ns#' term='Micro Framework'/><title type='text'>FEZ Domino</title><content type='html'>&lt;p&gt;Un rapide post pour vous faire partager ma joie de ce jour.&lt;/p&gt;
&lt;p&gt;J'ai enfin reçu la commande que j'avais passé sur &lt;a href="http://www.robotshop.com/eu/"&gt;Roboshop&lt;/a&gt; il y a bientôt un mois (ils déconnent un peu chez Roboshop sur les délai...)
Bref, entre autre dans le colis :
&lt;ol&gt;
&lt;li&gt;Micro-contrôleur &lt;a href="http://www.ghielectronics.com/catalog/product/133"&gt;Fez Domino&lt;/a&gt;
   &lt;ul&gt;
     &lt;li&gt;Processeur 72Mhz 32-bit ARM7 LPC2388&lt;/li&gt;
     &lt;li&gt;~148KB free Flash&lt;/li&gt;
     &lt;li&gt;~62KB free RAM&lt;/li&gt;
   &lt;/ul&gt;
   &lt;br/&gt;
   &lt;img alt="fez domino" src="http://fabrice.michellonet.free.fr/MyMemoryLeaks/Posts/42/FEZ_Domino.JPG"/&gt;
&lt;/li&gt;
   &lt;br/&gt;
&lt;li&gt;Un servo controlleur &lt;a href="http://www.lynxmotion.com/p-395-ssc-32-servo-controller.aspx"&gt;SSC-32&lt;/a&gt;
   &lt;ul&gt;
     &lt;li&gt;Peut gérer jusqu'à 32 servo moteurs.&lt;/li&gt;
   &lt;/ul&gt;
&lt;br/&gt;
   &lt;img alt="SSC-32" src="http://fabrice.michellonet.free.fr/MyMemoryLeaks/Posts/42/SSC32.JPG"/&gt;
&lt;/li&gt;
&lt;br/&gt;
&lt;/ol&gt;
C'est vraiment petit ces trucs la, pour vous donner une idée, les voici à côté d'une pile 9V.
&lt;br/&gt;&lt;br/&gt;
&lt;img alt="Domino &amp; SSC-32" src="http://fabrice.michellonet.free.fr/MyMemoryLeaks/Posts/42/Domino&amp;SSC32.JPG"/&gt;
&lt;/p&gt;
&lt;p&gt;Mon premier défit va être de tenter le portage d'un &lt;a href="http://en.wikipedia.org/wiki/Dependency_injection"&gt;conteneur DI&lt;/a&gt; sur cette plateforme. Je sens que ça va être chaud!&lt;/p&gt;
&lt;p&gt;Ensuite, je crois que je vais tenter la construction d'un &lt;a href="http://fr.wikipedia.org/wiki/Robot_hexapode"&gt;Hexapode&lt;/a&gt;... d’où l'achat du SSC-32.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1146316188254265608-535820351817854973?l=mymemoryleaks.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mymemoryleaks.blogspot.com/feeds/535820351817854973/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1146316188254265608&amp;postID=535820351817854973' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1146316188254265608/posts/default/535820351817854973'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1146316188254265608/posts/default/535820351817854973'/><link rel='alternate' type='text/html' href='http://mymemoryleaks.blogspot.com/2011/07/fez-domino.html' title='FEZ Domino'/><author><name>Fabrice Michellonet</name><uri>http://www.blogger.com/profile/10201820062243684793</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_yYUu3sWKdtU/SE76j2im4AI/AAAAAAAACFA/OgO15yojzu8/S220/Fabrice_MICHELLONET.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1146316188254265608.post-7742361934671179583</id><published>2011-06-21T23:32:00.003+02:00</published><updated>2011-07-11T15:46:40.827+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ASP.NET MVC'/><category scheme='http://www.blogger.com/atom/ns#' term='Nuget'/><category scheme='http://www.blogger.com/atom/ns#' term='Visual Studio'/><title type='text'>Custom ASP.NET MVC Project Template</title><content type='html'>&lt;p&gt;Récemment, Phil Haack nous présentait dans un très bon post &lt;a href="http://haacked.com/archive/2011/06/06/creating-a-custom-asp-net-mvc-project-template.aspx"&gt;comment ajouter un template MVC3 personnalisé&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Dans ce post il lève le voile sur l'intégration de &lt;a href="http://nuget.org/"&gt;nuget&lt;/a&gt; dans Visual Studio. On y apprend que malheureusement par manque de temps l'intégration n'est que minimaliste et que seul les packages présent sur la machine (%ProgramFiles%\Microsoft ASP.NET\ASP.NET MVC 3\Packages) ne peuvent être installés.&lt;/p&gt;
&lt;p&gt;Après avoir fait un peu joujou avec, voici quelques points complémentaires : 
&lt;ul&gt;
&lt;li&gt;Pour télécharger un package nuget (extension nupkg), vous pouvez utiliser &lt;a href="http://nuget.codeplex.com/releases/view/59864"&gt;nuget package explorer&lt;/a&gt;&lt;/li&gt;&lt;br/&gt;
&lt;li&gt;Il n'y a pas de résolution de dépendance entre package. Vous devez donc les ordonner dans la section WizardData :
&lt;pre class="brush: csharp"&gt;
&amp;lt;WizardData&amp;gt;
    &amp;lt;packages&amp;gt;
        &amp;lt;package id=&amp;quot;jQuery&amp;quot; version=&amp;quot;1.5.1&amp;quot; /&amp;gt;
        &amp;lt;package id=&amp;quot;jQuery.Validation&amp;quot; version=&amp;quot;1.8.0&amp;quot; /&amp;gt;
        &amp;lt;package id=&amp;quot;jQuery.UI.Combined&amp;quot; version=&amp;quot;1.8.11&amp;quot; /&amp;gt;
    &amp;lt;/packages&amp;gt;
&amp;lt;/WizardData&amp;gt;
&lt;/pre&gt;
&lt;/li&gt;&lt;br/&gt;
&lt;li&gt;Les template de quickstart (plusieurs projets) fonctionnent dans cette configuration et peuvent tirer parti de l'installation de packages via nuget.&lt;/li&gt;&lt;br/&gt;
&lt;li&gt;Il m'est arrivé a plusieurs reprise de noter que la commande 
&lt;pre class="brush: ps"&gt;
devenv /installvstemplates
&lt;/pre&gt; ne suffisait a rafraichir le cache de template de Visual Studio. Un reboot de la machine remet tout dans l'ordre.&lt;/li&gt;&lt;br/&gt;
&lt;/ul&gt;
&lt;/p&gt;

&lt;p&gt;Happy Nuget!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1146316188254265608-7742361934671179583?l=mymemoryleaks.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mymemoryleaks.blogspot.com/feeds/7742361934671179583/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1146316188254265608&amp;postID=7742361934671179583' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1146316188254265608/posts/default/7742361934671179583'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1146316188254265608/posts/default/7742361934671179583'/><link rel='alternate' type='text/html' href='http://mymemoryleaks.blogspot.com/2011/06/custom-aspnet-mvc-project-template.html' title='Custom ASP.NET MVC Project Template'/><author><name>Fabrice Michellonet</name><uri>http://www.blogger.com/profile/10201820062243684793</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_yYUu3sWKdtU/SE76j2im4AI/AAAAAAAACFA/OgO15yojzu8/S220/Fabrice_MICHELLONET.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1146316188254265608.post-4414461101769599008</id><published>2011-05-17T21:00:00.005+02:00</published><updated>2011-06-21T23:35:11.192+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Nuget'/><category scheme='http://www.blogger.com/atom/ns#' term='Obsidian'/><category scheme='http://www.blogger.com/atom/ns#' term='Visual Studio'/><title type='text'>Quickstart &amp; Nuget</title><content type='html'>&lt;p&gt;Dans mon &lt;a href="http://mymemoryleaks.blogspot.com/2011/05/project-template-quickstart-et-vsix.html"&gt;précédent post&lt;/a&gt; j’effleurais le sujet des gains de productivité que pouvais procurer les templates et autres Quickstart dans vos développement de tous les jours.&lt;/p&gt;
&lt;p&gt;Prenons le cas d’un Quickstart, qui je le rappelle n’est autre qu’une solution templatisée. Imaginons que l’on souhaite utiliser 3 ou 4 librairies externes .NET bien sentie et pourquoi pas une ou deux librairies javascript s’il s’agit d’une solution Web.&lt;/p&gt;
&lt;p&gt;En m’appuyant sur &lt;a href="http://nuget.codeplex.com/"&gt;Nuget&lt;/a&gt; lors de la création des templates de projet composant le Quickstart, les dépendances pourrons être facilement être mise à jour par les développeurs à posteriori toujours grâce à Nuget. Rien de magique dans tout ça, en fait chaque projet est doté de son propre fichier 'packages.config' (repository nuget pour le projet) relatant la version des librairies référencées.&lt;/p&gt;
&lt;p&gt;Voici ce que j’aimerais mettre en place en plus : 
&lt;ul&gt;
&lt;li&gt;Mise à jour automatique de nuget avant toute autre opération.&lt;/li&gt;
&lt;li&gt;Téléchargement et installation automatisée des dépendances référencées pour chaque projet.&lt;/li&gt;
&lt;li&gt;Mise à jour automatique des dépendances lors de la première installation.&lt;/li&gt;
&lt;/ul&gt;
&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Infos complémentaires :&lt;/p&gt;
&lt;p&gt;Microsoft depuis le &lt;a href="http://www.microsoft.com/downloads/en/details.aspx?FamilyID=82cbd599-d29a-43e3-b78b-0f863d22811a&amp;displaylang=en"&gt;MVC3 Tool Update&lt;/a&gt; du 12 Avril 2011 propose un nouveau template de projet MVC3 basé lui aussi sur nuget. La technique utilisée est quelque peu différente de celle que je vous présente ici, mais ne permet pas la mise à jour automatique des dépendances à l’installation.&lt;/p&gt;
&lt;p&gt;Je reviendrais surement très rapidement sur cette façon de faire dans un prochain billet.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Pour réaliser ces différents points il nous faudra coder un &lt;a href="http://msdn.microsoft.com/en-us/library/microsoft.visualstudio.templatewizard.iwizard%28v=VS.100%29.aspx"&gt;Wizard&lt;/a&gt; custom.&lt;/p&gt;
&lt;p&gt;La première tâche consistant à déployer nuget.exe est simplissime. Il nous suffit de l’embarquer dans les ressources de notre Wizard, puis au runtime extraire l’exécutable et le copier par exemple dans le dossier « packages » au sein de la solution. Pour info, le dossier « package » est utilisé par nuget pour y stocker les dépendances qu’il a téléchargé.&lt;/p&gt;
&lt;pre class="brush: csharp"&gt;
DirectoryInfo packageDirInfo = _solutionDirInfo.CreateSubdirectory("packages");
string _nugetFilePath = Path.Combine(packageDirInfo.FullName, "Nuget.exe");
File.WriteAllBytes(_nugetFilePath, Resources.NuGet);
&lt;/pre&gt;
&lt;p&gt;
Notez que le dossier package doit absolument se trouvé dans le même répertoire que votre fichier sln, si vous voulez pouvoir profiter de la mise à jour des packages. Il s’agit d’une restriction imposé par nuget lui-même
&lt;/p&gt;
&lt;p&gt;
Nuget déployé, il est possible de le mettre à jour automatiquement en exécutant la ligne de commande suivante :
&lt;/p&gt;
&lt;pre class="brush: ps"&gt;nuget update&lt;/pre&gt;
&lt;p&gt;Dans notre Wizard on pourra utiliser le code suivant : &lt;/p&gt;
&lt;pre class="brush: csharp"&gt;
Process nugetProc = new Process
            {
                StartInfo = new ProcessStartInfo(_nugetFilePath)
                {
                    Arguments = "update",
                    RedirectStandardError = true,
                    RedirectStandardOutput = true,
                    UseShellExecute = false,
                    CreateNoWindow = true
                },
            };
            nugetProc.Start();
            StreamReader output = nugetProc.StandardOutput;
            StreamReader error = nugetProc.StandardError;
            nugetProc.WaitForExit();
&lt;/pre&gt;
&lt;p&gt;
Concernant l’installation des dépendances de chaque projet se fera simplement en utilisant une fois de plus une ligne de commande ; que l’on créera en C# de la manière suivante : 
&lt;/p&gt;
&lt;pre class="brush: csharp"&gt;
Process nugetProc = new Process
            {
                StartInfo = new ProcessStartInfo(_nugetFilePath)
                {
                    Arguments = string.Format("install {0}", _packageFilePath),
                    RedirectStandardError = true,
                    RedirectStandardOutput = true,
                    UseShellExecute = false,
                    CreateNoWindow = true,
                    WorkingDirectory = new FileInfo(_nugetFilePath).DirectoryName
                 },
            };
            nugetProc.Start();
&lt;/pre&gt;
&lt;p&gt;
L’idée ici est en fait d’exécuter 1 fois pour chacun de vos projets la commande suivante : &lt;/p&gt;
&lt;pre class="brush: ps"&gt;nuget install %path/to%/packages.config&lt;/pre&gt;
&lt;p&gt;
Reste encore la tache de mettre à jour toutes les dépendances. Malheureusement, pour l’instant nuget.exe ne propose pas encore de commande permettant la mise à jour des dépendances. Cependant un récent &lt;a href="#"&gt;post&lt;/a&gt;, &lt;a href="http://haacked.com/"&gt;Phil Haack&lt;/a&gt; annonce la disponibilité de cette option pour la version de 1.4 de nuget.
&lt;/p&gt;
&lt;p&gt;En attendant cette fonctionnalité, nous pouvons nous en sortir en installant par default le package &lt;a href="http://nuget.org/List/Packages/NuGetPackageUpdater"&gt;NuGetPackageUpdater&lt;/a&gt;. Ce dernier vous offre la possibilité d’exécuter la commande 'Update-Package' qui se chargera d’effectuer la mise à jour de toutes les dépendances de la solution.&lt;/p&gt;
&lt;p&gt;J’espère qu’en suivant ces instructions vous pourrez construire des Templates qui se mettrons à jour tout seul.&lt;/p&gt;
&lt;p&gt;Pour ceux qui souhaiteraient jeter un coup d’œil plus approfondi au code que je viens de présenter, il est disponible sur &lt;a href="http://www.codeplex.com/"&gt;Codeplex&lt;/a&gt; avec l’ensemble des briques du Quikstart &lt;a href="http://obsidian.codeplex.com/"&gt;Obsidian&lt;/a&gt; sur lequel je travaille actuellement.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1146316188254265608-4414461101769599008?l=mymemoryleaks.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mymemoryleaks.blogspot.com/feeds/4414461101769599008/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1146316188254265608&amp;postID=4414461101769599008' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1146316188254265608/posts/default/4414461101769599008'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1146316188254265608/posts/default/4414461101769599008'/><link rel='alternate' type='text/html' href='http://mymemoryleaks.blogspot.com/2011/05/quickstart-nuget.html' title='Quickstart &amp; Nuget'/><author><name>Fabrice Michellonet</name><uri>http://www.blogger.com/profile/10201820062243684793</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_yYUu3sWKdtU/SE76j2im4AI/AAAAAAAACFA/OgO15yojzu8/S220/Fabrice_MICHELLONET.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1146316188254265608.post-7767491471490552912</id><published>2011-05-13T23:29:00.000+02:00</published><updated>2011-05-13T23:29:16.839+02:00</updated><title type='text'>Project Template, Quickstart et VSIX</title><content type='html'>&lt;p&gt;Dernièrement j’ai fait mumuse avec les template de fichiers et projets que l’on peut créer dans Visual Studio.&lt;/p&gt;
&lt;img src="http://fabrice.michellonet.free.fr/MyMemoryLeaks/Posts/41/coccinelle.png" alt="coccinelle"/&gt;
&lt;p&gt;Pour ceux qui ne connaissent pas, les template de fichier vous permettent de définir l’ossature d’un type de fichier que vous utilisez souvent.  Une fois créé vous retrouverez votre template dans le menu de Visual Studio « Add new Item ».&lt;/p&gt;

&lt;p&gt;Par extension les projects template vous permettent de définir la structure d’un type projet, afin de prendre en compte les conventions de votre équipe par exemple. Vous y définissez l’ensemble des fichiers présent dès la création du projet.&lt;/p&gt;

&lt;p&gt;Ce qui est très intéressant, c'est que cela permet d'avoir des projets prêts à l'emploi dans votre environnement, avec par exemple &lt;a href="http://nlog-project.org/"&gt;NLog&lt;/a&gt;&amp;nbsp;&lt;a href="http://www.blogger.com/post-create.g?blogID=1146316188254265608"&gt;et votre conteneur &lt;/a&gt;&lt;a href="http://martinfowler.com/articles/injection.html"&gt;DI&lt;/a&gt; &lt;a href="http://www.castleproject.org/"&gt;préféré&lt;/a&gt;. Si vous êtes expérimenté cela vous évitera quelques copier-coller,  si par contre vous ne connaissez pas bien une des briques technique cela vous évitera un tas de problématique.&lt;/p&gt;

&lt;p&gt;Quoi qu'il en soit voici quelques astuces sur ces templates :&lt;p/&gt;

&lt;ol&gt;&lt;br/&gt;
&lt;li&gt;Bien que le &lt;a href="http://www.microsoft.com/downloads/en/details.aspx?FamilyID=21307c23-f0ff-4ef2-a0a4-dca54ddb1e21"&gt;SDK&lt;/a&gt; de Visual Studio vous propose des projets de type Item Template et Project Template, le plus simple reste d’utiliser le menu File -&amp;gt; Export Template de Viual Studio pour générer votre précieux template.&lt;/li&gt;&lt;br/&gt;
&lt;li&gt;Pour créer un quickstart, qui n’est autre qu’un template de solution (plusieurs projets), je vous conseille de : &lt;/li&gt;
&lt;ol&gt;&lt;br/&gt;
&lt;li&gt;Exporter vos différents projets template et extraire les archives zip correspondante dans un même dossier.&lt;/li&gt;&lt;br/&gt;
&lt;li&gt;Ajouter dans ce dossier de travail un fichier .vstemplate reprenant cette structure&lt;/li&gt;&lt;br/&gt;
&lt;pre class="brush: xml"&gt;
&amp;lt;VSTemplate Version="2.0.0" xmlns="http://schemas.microsoft.com/developer/vstemplate/2005" Type="ProjectGroup"&amp;gt;
  &amp;lt;TemplateData&amp;gt;
    &amp;lt;Name&amp;gt;Ma solution&amp;lt;/Name&amp;gt;
    &amp;lt;Description&amp;gt;Ma description&amp;lt;/Description&amp;gt;
    &amp;lt;ProjectType&amp;gt;CSharp&amp;lt;/ProjectType&amp;gt;
    &amp;lt;ProjectSubType&amp;gt;&amp;lt;/ProjectSubType&amp;gt;
    &amp;lt;SortOrder&amp;gt;1000&amp;lt;/SortOrder&amp;gt;
    &amp;lt;CreateNewFolder&amp;gt;false&amp;lt;/CreateNewFolder&amp;gt;
    &amp;lt;LocationField&amp;gt;Enabled&amp;lt;/LocationField&amp;gt;
    &amp;lt;EnableLocationBrowseButton&amp;gt;true&amp;lt;/EnableLocationBrowseButton&amp;gt;
    &amp;lt;Icon&amp;gt;monicone_100x100.ico&amp;lt;/Icon&amp;gt;
  &amp;lt;/TemplateData&amp;gt;
  &amp;lt;TemplateContent&amp;gt;
    &amp;lt;ProjectCollection&amp;gt;
      &amp;lt;ProjectTemplateLink ProjectName="Web"&amp;gt;
        Web\MyTemplate.vstemplate
      &amp;lt;/ProjectTemplateLink&amp;gt;
      &amp;lt;ProjectTemplateLink ProjectName="Domain"&amp;gt;
        Domain\MyTemplate.vstemplate
      &amp;lt;/ProjectTemplateLink&amp;gt;
      &amp;lt;ProjectTemplateLink ProjectName="DAL"&amp;gt;
        DAL\MyTemplate.vstemplate
      &amp;lt;/ProjectTemplateLink&amp;gt;
      &amp;lt;ProjectTemplateLink ProjectName="IServices"&amp;gt;
        IServices\MyTemplate.vstemplate
      &amp;lt;/ProjectTemplateLink&amp;gt;
      &amp;lt;ProjectTemplateLink ProjectName="Services"&amp;gt;
        Services\MyTemplate.vstemplate
      &amp;lt;/ProjectTemplateLink&amp;gt;
    &amp;lt;/ProjectCollection&amp;gt;
  &amp;lt;/TemplateContent&amp;gt;
&amp;lt;/VSTemplate&amp;gt;
&lt;/pre&gt;
&lt;p&gt;Vous pouvez y mettre autant de référence a des projects que vous le souhaitez en ajoutant des balises ProjectTemplateLink.&lt;/p&gt;
&lt;li&gt;Créez une archive zip du dossier de travail et placez la dans le dossier %VSInstallDir%\Common7\IDE\ProjectTemplates\. Après redémarrage de Visual Studio le nouveau template sera dispo.&lt;/li&gt;&lt;br/&gt;
&lt;/ol&gt;
&lt;li&gt;Dans le fichier vstemplate de votre Quickstart, la première occurrence à un projet sera par convention le startup project.&lt;/li&gt;&lt;br/&gt;
&lt;li&gt;Pour étendre avec du code custom vos project template il vous faudra :&lt;/li&gt;&lt;br/&gt;
&lt;ol&gt;
&lt;li&gt;Créer une assembly et implémenter l’interface &lt;a href="http://msdn.microsoft.com/en-us/library/microsoft.visualstudio.templatewizard.iwizard%28v=VS.100%29.aspx"&gt;Microsoft.VisualStudio.TemplateWizard.IWizard&lt;/a&gt;&lt;/li&gt;&lt;br/&gt;
&lt;li&gt;Ajouter la balise WizardExtension dans le fichier .vstemplate de votre project template&lt;/li&gt;&lt;br/&gt;
&lt;pre class="brush: xml"&gt;
&amp;lt;VSTemplate Version=&amp;quot;3.0.0&amp;quot; xmlns=&amp;quot;http://schemas.microsoft.com/developer/vstemplate/2005&amp;quot; Type=&amp;quot;Project&amp;quot;&amp;gt;
  …
  &amp;lt;WizardExtension&amp;gt;
    &amp;lt;Assembly&amp;gt;MyAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=952e5fc020f3b126&amp;lt;/Assembly&amp;gt;
    &amp;lt;FullClassName&amp;gt;MyAssembly.Wizard&amp;lt;/FullClassName&amp;gt;
  &amp;lt;/WizardExtension&amp;gt;
&amp;lt;/VSTemplate&amp;gt;
&lt;/pre&gt;
&lt;/ol&gt;
&lt;li&gt;Il est possible de faire appel à une assembly custom dans un template de type quickstart, mais attention, la plupart des appels que vous ferez sur les objects EnvDTE et plus particulièrement &lt;a href="http://msdn.microsoft.com/en-us/library/envdte.project.aspx"&gt;EnvDTE.Project&lt;/a&gt; fréquemment utilisés dans la méthode &lt;a href="http://msdn.microsoft.com/en-us/library/microsoft.visualstudio.templatewizard.iwizard.projectitemfinishedgenerating.aspx"&gt;IWizard. ProjectFinishedGenerating&lt;/a&gt; vous renverront des valeurs nulles.&lt;/li&gt;&lt;br/&gt;
&lt;li&gt;La façon la plus simple de créer un VSIX de déploiement est d’utiliser le projet de type VSIX Project  (Visual C# -&gt; Extensibility -&gt; VSIX Project). Le &lt;a href="http://www.microsoft.com/downloads/en/details.aspx?FamilyID=21307c23-f0ff-4ef2-a0a4-dca54ddb1e21"&gt;SDK&lt;/a&gt; doit être installé.&lt;/li&gt;&lt;br/&gt;
&lt;li&gt;Dans le designer de VSIX, le champ ID comporte un GUID… n’y touchez surtout pas !&lt;/li&gt;&lt;br/&gt;
&lt;li&gt;Il est possible de définir dans quelle catégorie de template se trouvera l’élément que vous déployez via votre VSIX en renseignant le champ Add to subfolder.&lt;/li&gt;&lt;br/&gt;
&lt;img src="http://fabrice.michellonet.free.fr/MyMemoryLeaks/Posts/41/subfolder.png" alt="subfolder"/&gt;
&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1146316188254265608-7767491471490552912?l=mymemoryleaks.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mymemoryleaks.blogspot.com/feeds/7767491471490552912/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1146316188254265608&amp;postID=7767491471490552912' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1146316188254265608/posts/default/7767491471490552912'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1146316188254265608/posts/default/7767491471490552912'/><link rel='alternate' type='text/html' href='http://mymemoryleaks.blogspot.com/2011/05/project-template-quickstart-et-vsix.html' title='Project Template, Quickstart et VSIX'/><author><name>Fabrice Michellonet</name><uri>http://www.blogger.com/profile/10201820062243684793</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_yYUu3sWKdtU/SE76j2im4AI/AAAAAAAACFA/OgO15yojzu8/S220/Fabrice_MICHELLONET.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1146316188254265608.post-6643593530380600053</id><published>2011-03-31T23:04:00.003+02:00</published><updated>2011-06-21T23:36:32.252+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ASP.NET MVC'/><category scheme='http://www.blogger.com/atom/ns#' term='Nuget'/><title type='text'>Quickstart Telerik Extensions for ASP.NET MVC via Nuget</title><content type='html'>&lt;p&gt;Sans nul doute &lt;a href="http://scribefire-next/"&gt;Nuget&lt;/a&gt; a grandement am&amp;eacute;lior&amp;eacute; le process de d&amp;eacute;ploiement/configuration/utilisation de biblioth&amp;egrave;ques tierces dans l'&amp;eacute;cosyst&amp;egrave;me .NET.&lt;/p&gt;&lt;p&gt;Malheureusement, certain package ne sont pas parfait, et nécessite que l'on trifouille encore un peu dans la config pour que tout soit fonctionnel.&lt;br /&gt;J'en ai personnellement fait l'exp&amp;eacute;rience lorsque j'ai tent&amp;eacute; d'utiliser les &lt;a href="http://www.telerik.com/products/aspnet-mvc.aspx"&gt;MVC Extensions de Telerik&lt;/a&gt; via Nuget, une excellente librairie de composants graphiques soit dit en passant.&lt;/p&gt;&lt;p&gt;Vous l'aurez compris, l'id&amp;eacute;e de ce post est de pr&amp;eacute;senter les manipulations &amp;agrave; faire pour pouvoir finaliser l'installation de la librairie de Telerik.&lt;/p&gt;&lt;p&gt;&lt;img src="http://fabrice.michellonet.free.fr/MyMemoryLeaks/Posts/40/nuget.png" alt="nuget"/&gt;&amp;nbsp;&amp;nbsp;&lt;img src="http://fabrice.michellonet.free.fr/MyMemoryLeaks/Posts/40/Telerik-MVC.jpg" alt="telerik mvc extensions"/&gt;&lt;/p&gt;&lt;p&gt;On commence par demander l'installation du package :&lt;/p&gt;&lt;pre class="brush: ps"&gt;
Install-Package TelerikMvcExtensions
&lt;/pre&gt;&lt;p&gt;Pas d'inquiétude, si cela prend un peu de temps, c'est normal; il y a un paquet de fichier a rapatrier puis &amp;agrave; ajouter dans la solution.&lt;/p&gt;&lt;p&gt;Une fois que c'est fait, si vous ouvrez une vue, vous vous rendrez compte que malheureusement, l'intellisense ne vous propose rien de nouveau. Pire, s'il vous prenait l'envie de copier coller un exemple de code issue du site de Telerik, vous auriez un joli plantage.&lt;/p&gt;&lt;p&gt;Pour corriger tout ça, on va trifouiller dans le web.config. Ci-dessous les &amp;eacute;l&amp;egrave;ments &amp;agrave; ajouter :&lt;/p&gt;&lt;pre class="brush:xml"&gt;

&amp;lt;configuration&amp;gt;
  &amp;lt;configSections&amp;gt;
    &amp;lt;sectionGroup name=&amp;quot;telerik&amp;quot;&amp;gt;
      &amp;lt;section name=&amp;quot;webAssets&amp;quot; type=&amp;quot;Telerik.Web.Mvc.Configuration.WebAssetConfigurationSection, Telerik.Web.Mvc&amp;quot; requirePermission=&amp;quot;false&amp;quot; /&amp;gt;
    &amp;lt;/sectionGroup&amp;gt;

    &amp;lt;sectionGroup name=&amp;quot;system.web.webPages.razor&amp;quot; type=&amp;quot;System.Web.WebPages.Razor.Configuration.RazorWebSectionGroup, System.Web.WebPages.Razor, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35&amp;quot;&amp;gt;
      &amp;lt;section name=&amp;quot;host&amp;quot; type=&amp;quot;System.Web.WebPages.Razor.Configuration.HostSection, System.Web.WebPages.Razor, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35&amp;quot; requirePermission=&amp;quot;false&amp;quot; /&amp;gt;
      &amp;lt;section name=&amp;quot;pages&amp;quot; type=&amp;quot;System.Web.WebPages.Razor.Configuration.RazorPagesSection, System.Web.WebPages.Razor, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35&amp;quot; requirePermission=&amp;quot;false&amp;quot; /&amp;gt;
    &amp;lt;/sectionGroup&amp;gt;
  &amp;lt;/configSections&amp;gt;

  &amp;lt;system.web&amp;gt;
    &amp;lt;pages&amp;gt;
      &amp;lt;namespaces&amp;gt;
        &amp;lt;add namespace=&amp;quot;Telerik.Web.Mvc.UI&amp;quot; /&amp;gt;
      &amp;lt;/namespaces&amp;gt;
    &amp;lt;/pages&amp;gt;

    &amp;lt;httpHandlers&amp;gt;
      &amp;lt;add verb=&amp;quot;GET,HEAD&amp;quot; path=&amp;quot;asset.axd&amp;quot; validate=&amp;quot;false&amp;quot; type=&amp;quot;Telerik.Web.Mvc.WebAssetHttpHandler, Telerik.Web.Mvc&amp;quot; /&amp;gt;
    &amp;lt;/httpHandlers&amp;gt;
  &amp;lt;/system.web&amp;gt;

  &amp;lt;system.webServer&amp;gt;

    &amp;lt;handlers&amp;gt;
      &amp;lt;remove name=&amp;quot;asset&amp;quot; /&amp;gt;
      &amp;lt;add name=&amp;quot;asset&amp;quot; preCondition=&amp;quot;integratedMode&amp;quot; verb=&amp;quot;GET,HEAD&amp;quot; path=&amp;quot;asset.axd&amp;quot; type=&amp;quot;Telerik.Web.Mvc.WebAssetHttpHandler, Telerik.Web.Mvc&amp;quot; /&amp;gt;
    &amp;lt;/handlers&amp;gt;

  &amp;lt;/system.webServer&amp;gt;

  &amp;lt;telerik&amp;gt;
    &amp;lt;webAssets useTelerikContentDeliveryNetwork=&amp;quot;false&amp;quot; /&amp;gt;
  &amp;lt;/telerik&amp;gt;

  &amp;lt;system.web.webPages.razor&amp;gt;
    &amp;lt;host factoryType=&amp;quot;System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35&amp;quot; /&amp;gt;
    &amp;lt;pages pageBaseType=&amp;quot;System.Web.Mvc.WebViewPage&amp;quot;&amp;gt;
      &amp;lt;namespaces&amp;gt;
        &amp;lt;add namespace=&amp;quot;System.Web.Mvc&amp;quot; /&amp;gt;
        &amp;lt;add namespace=&amp;quot;System.Web.Mvc.Ajax&amp;quot; /&amp;gt;
        &amp;lt;add namespace=&amp;quot;System.Web.Mvc.Html&amp;quot; /&amp;gt;
        &amp;lt;add namespace=&amp;quot;System.Web.Routing&amp;quot; /&amp;gt;
        &amp;lt;add namespace=&amp;quot;Telerik.Web.Mvc.UI&amp;quot; /&amp;gt;
      &amp;lt;/namespaces&amp;gt;
    &amp;lt;/pages&amp;gt;
  &amp;lt;/system.web.webPages.razor&amp;gt;

&amp;lt;/configuration&amp;gt;
&lt;/pre&gt;&lt;p&gt;Ouf! ca y est on a rajout&amp;eacute; tout ce qu'il nous manquait.&lt;/p&gt;&lt;p&gt;En ouvrant de nouveau une vue, l'intellisense devrait se mettre a vous proposer de nouvelles choses dans le namespace Telerik. Parfois, l'intellisense reste muet et je n'ai pas trouv&amp;eacute; d'autres alternatives que de redemarrer mon Visual Studio 2010.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Edit -- 18/04&lt;/b&gt;&lt;br/&gt;
Evidemment, il nous faut également modifier la master page afin d'y ajouter les styles et les scripts de Telerik.
&lt;pre class="brush:html"&gt;
&amp;lt;head&amp;gt;
    ...
    @(Html.Telerik().StyleSheetRegistrar().DefaultGroup(group =&amp;gt; group.Add(&amp;quot;telerik.common.css&amp;quot;).Add(&amp;quot;telerik.windows7.css&amp;quot;).Add(&amp;quot;telerik.rtl.css&amp;quot;).Combined(true).Compress(true)))
&amp;lt;/head&amp;gt;

&amp;lt;/body&amp;gt;
@(Html.Telerik().ScriptRegistrar().Globalization(true).DefaultGroup(group =&amp;gt; group.Combined(true).Compress(true)))
&amp;lt;/html&amp;gt;
&lt;/pre&gt;
&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;Ok, ok m'sieur Michellonet c'est bien beau tout ça, mais pourquoi j'irais utiliser la librairie de Telerik... en deux mots!&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;Tout simplement parce que la grille est géniale, elle a toutes les fonctionnalités que l'on peut attendre d'une grille Web 3.0 :p&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1146316188254265608-6643593530380600053?l=mymemoryleaks.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mymemoryleaks.blogspot.com/feeds/6643593530380600053/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1146316188254265608&amp;postID=6643593530380600053' title='1 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1146316188254265608/posts/default/6643593530380600053'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1146316188254265608/posts/default/6643593530380600053'/><link rel='alternate' type='text/html' href='http://mymemoryleaks.blogspot.com/2011/03/quickstart-telerik-extensions-for.html' title='Quickstart Telerik Extensions for ASP.NET MVC via Nuget'/><author><name>Fabrice Michellonet</name><uri>http://www.blogger.com/profile/10201820062243684793</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_yYUu3sWKdtU/SE76j2im4AI/AAAAAAAACFA/OgO15yojzu8/S220/Fabrice_MICHELLONET.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1146316188254265608.post-7247112430802839676</id><published>2011-03-22T19:38:00.002+01:00</published><updated>2011-03-23T00:47:07.367+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Mercurial'/><title type='text'>Mercurial : Régler les problèmes de certificats SSL.</title><content type='html'>&lt;p&gt;Ce n'est pas dans mon habitude de poster des conseils sur des outils et leur configuration, mais cette fois je vais faire une petite entorse au r&amp;egrave;glement; tout simplement car j'ai pas mal gal&amp;eacute;r&amp;eacute; pour r&amp;eacute;soudre ce soucis, et si ce post permet d'aider une seule personne alors cela en aura valu le coup.&lt;/p&gt;&lt;p&gt;Bref, depuis la version 1.7 le niveau de s&amp;eacute;curit&amp;eacute; de Mercurial &amp;agrave; &amp;eacute;t&amp;eacute; revu &amp;agrave; la hausse, et donc &amp;eacute;videment des petits tracas pour nous utilisateurs de &lt;a href="http://tortoisehg.bitbucket.org/"&gt;Tortoise HG&lt;/a&gt; &amp;amp; &lt;a href="http://visualhg.codeplex.com/"&gt;Visual HG&lt;/a&gt; sous Windows. En r&amp;eacute;sum&amp;eacute;, les connexions HTTPS utilisant des certificats auto sign&amp;eacute;s (Self-signed certificates) ne sont plus accept&amp;eacute;s par le controleur de code source.&lt;/p&gt;&lt;p&gt;&lt;img src="http://fabrice.michellonet.free.fr/MyMemoryLeaks/Posts/39/Tortoise.jpg" alt="" /&gt;&lt;/p&gt;&lt;p&gt;La &lt;a href="http://mercurial.selenic.com/wiki/CACertificates"&gt;documentation&lt;/a&gt; stipule qu'il est possible de rajouter dans le fichier cacert.pem de Tortoise le certificat que vous souhaitez autoriser; Le probl&amp;egrave;me est qu'il va vous falloir utiliser &lt;a href="http://www.openssl.org/"&gt;openssl&lt;/a&gt;, non pr&amp;eacute;sent en standard sur un Windows. Je vous avouerais que je n'ai m&amp;ecirc;me pas tent&amp;eacute; de le t&amp;eacute;l&amp;eacute;charger et de l'utiliser; Alors peut-&amp;ecirc;tre est-ce facilement faisable sous Windows... personnellement j'avais peur de me lancer dans une gal&amp;egrave;re de plus.&lt;/p&gt;&lt;p&gt;Par contre, laissez-moi vous montrer une fa&amp;ccedil;on de faire beaucoup plus simple, pour nous Windowsien de base et tout aussi s&amp;eacute;curis&amp;eacute;e.&lt;/p&gt;&lt;p&gt;L'id&amp;eacute;e est d'ajouter l'empreinte num&amp;eacute;rique du serveur h&amp;eacute;bergeant le repository dans la configuration de Tortoise; la doc &amp;eacute;tant un peu l&amp;eacute;g&amp;egrave;re sur ce point, voici les &amp;eacute;tapes pour y arriver.&lt;/p&gt;&lt;p&gt;Bon, tout d'abord ouvrez votre &lt;a href="http://www.mozilla-europe.org/fr/"&gt;navigateur pr&amp;eacute;f&amp;eacute;r&amp;eacute;&lt;/a&gt; et rendez-vous sur la home page de votre repository. En cliquant sur le petit cadenas en bas de votre fen&amp;ecirc;tre vous devriez avoir une fen&amp;ecirc;tre comme celle-ci qui s'ouvre :&lt;/p&gt;&lt;p&gt;&lt;a href='http://fabrice.michellonet.free.fr/MyMemoryLeaks/Posts/39/Certificat.png' dojotype='dojox.image.Lightbox' group='1' title='Certificat'&gt;&lt;img src='http://fabrice.michellonet.free.fr/MyMemoryLeaks/Posts/39/Certificat_thumb.png' alt='Certificat'/&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Le bouton "afficher certifat" ouvre une nouvelle fen&amp;ecirc;tre dans laquelle vous copierez l'empreinte num&amp;eacute;rique SHA1. Cette empreinte identifie de mani&amp;egrave;re unique le serveur hebergeant votre repository Mercurial.&lt;/p&gt;&lt;p&gt;Ensuite, ouvrez Tortoise hg Workbench, puis dans la fen&amp;ecirc;tre de configuration, &amp;eacute;ditez le fichier de configuration mercurial.ini.&lt;/p&gt;&lt;p&gt;&lt;a href='http://fabrice.michellonet.free.fr/MyMemoryLeaks/Posts/39/mercurial_ini.png' dojotype='dojox.image.Lightbox' group='2' title='Config'&gt;&lt;img src='http://fabrice.michellonet.free.fr/MyMemoryLeaks/Posts/39/mercurial_ini_thumb.png' alt='Config'/&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Il ne reste plus qu'&amp;agrave; ajouter une section hostfingerprints reprenant l'adresse de votre server ainsi que son empreinte.&lt;/p&gt;&lt;p&gt;&lt;span lang="EN-US"&gt;[hostfingerprints]&lt;br /&gt;mercurial.devolis.com = ..:..:..:..:02:76:B5:29:65:47:A1:43:8E:0F:F5:13:03:AC:9D:0A&lt;/span&gt;&lt;/p&gt;&lt;p&gt;Voil&amp;agrave; enregistrez le fichier et tout devrait d&amp;eacute;sormais fonctionner comme avant.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1146316188254265608-7247112430802839676?l=mymemoryleaks.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mymemoryleaks.blogspot.com/feeds/7247112430802839676/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1146316188254265608&amp;postID=7247112430802839676' title='1 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1146316188254265608/posts/default/7247112430802839676'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1146316188254265608/posts/default/7247112430802839676'/><link rel='alternate' type='text/html' href='http://mymemoryleaks.blogspot.com/2011/03/mercurial-regler-les-problemes-de.html' title='Mercurial : Régler les problèmes de certificats SSL.'/><author><name>Fabrice Michellonet</name><uri>http://www.blogger.com/profile/10201820062243684793</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_yYUu3sWKdtU/SE76j2im4AI/AAAAAAAACFA/OgO15yojzu8/S220/Fabrice_MICHELLONET.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1146316188254265608.post-5361820150316189616</id><published>2011-02-28T23:47:00.001+01:00</published><updated>2011-02-28T23:48:12.133+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='ASP.NET MVC'/><title type='text'>Razor plugin pour SyntaxHighlighter</title><content type='html'>&lt;p&gt;Comme beaucoup d'entre vous j'utilise l'excellent &lt;a href="http://alexgorbatchev.com/SyntaxHighlighter/"&gt;SyntaxHighlighter&lt;/a&gt; d'Alex Gorbatchev, pour mettre en forme les snippets de code sur mon blog.&lt;/p&gt;&lt;p&gt;Bien qu'il dispose de nombreux plugin de prise en charge de language, parfois tr&amp;egrave;s &amp;eacute;sot&amp;eacute;rique, je n'ai encore rien vu pour le language pr&amp;eacute;f&amp;eacute;r&amp;eacute; de tous ceux qui font du MVC 3 ou du WebMatrix, j'ai nomm&amp;eacute; &lt;a href="http://www.asp.net/webmatrix/tutorials/2-introduction-to-asp-net-web-programming-using-the-razor-syntax"&gt;razor&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;img src="http://fabrice.michellonet.free.fr/MyMemoryLeaks/Posts/38/razor.jpg" alt="razor" /&gt;&lt;/p&gt;&lt;p&gt;Du coup, je me suis lanc&amp;eacute; et voici une toute premi&amp;egrave;re version t&amp;eacute;l&amp;eacute;chargeable &lt;a href="http://fabrice.michellonet.free.fr/MyMemoryLeaks/SH3/scripts/shBrushRazor.js"&gt;ici&lt;/a&gt;&lt;/p&gt;&lt;p&gt;et voici un exemple de mise en forme&lt;/p&gt;&lt;pre class="brush: razor;"&gt;
@model CustomMVCScaffolder.Models.Employee

@* This partial view defines form fields that will appear when creating and editing entities *@
&lt;div class="editor-label"&gt;
    @Html.LabelFor(model =&amp;gt; model.NationalIdNumber)&lt;/div&gt;
&lt;div class="editor-field"&gt;
    @Html.EditorFor(model =&amp;gt; model.NationalIdNumber)
    @Html.ValidationMessageFor(model =&amp;gt; model.NationalIdNumber)&lt;/div&gt;

@foreach (var ourItem in ourList) {
   if (ourItem != ourList.First()) {
      &lt;span&gt;outItem.Name&lt;/span&gt;
   }
}

@Html.ActionLink("Edit", "Edit", new {  id=item.UserName  }) |
@Html.ActionLink("Details", "Details", new {  id=item.UserName  }) |
@Html.ActionLink("Delete", "Delete", new {  id=item.UserName  })        

@Html.Hidden("UserName", Model.UserName)
&lt;/pre&gt;&lt;p&gt;Voici comment l'utiliser :&lt;/p&gt;&lt;pre class="brush: html;"&gt;
  &amp;lt;pre style="brush:razor"&amp;gt;
    @Html.Hidden("UserName", Model.UserName)
  &amp;lt;/pre&amp;gt;
&lt;/pre&gt;&lt;p&gt;J'esp&amp;egrave;re que cette petite contribution &amp;agrave; la communaut&amp;eacute; viendra enjoliver les snippets de code que l'on voit &amp;ccedil;a et l&amp;agrave;.&lt;/p&gt;&lt;p&gt;Ho... j'oubliais, si vous avez des propositions pour am&amp;eacute;liorer la mise en forme, je suis preneur.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1146316188254265608-5361820150316189616?l=mymemoryleaks.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mymemoryleaks.blogspot.com/feeds/5361820150316189616/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1146316188254265608&amp;postID=5361820150316189616' title='2 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1146316188254265608/posts/default/5361820150316189616'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1146316188254265608/posts/default/5361820150316189616'/><link rel='alternate' type='text/html' href='http://mymemoryleaks.blogspot.com/2011/02/razor-plugin-pour-syntaxhighlighter.html' title='Razor plugin pour SyntaxHighlighter'/><author><name>Fabrice Michellonet</name><uri>http://www.blogger.com/profile/10201820062243684793</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_yYUu3sWKdtU/SE76j2im4AI/AAAAAAAACFA/OgO15yojzu8/S220/Fabrice_MICHELLONET.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1146316188254265608.post-8492476905843542405</id><published>2011-02-22T23:52:00.003+01:00</published><updated>2011-02-22T23:58:10.098+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='MSBuild'/><category scheme='http://www.blogger.com/atom/ns#' term='Visual Studio'/><title type='text'>Transformations web.config d'une Web application.</title><content type='html'>&lt;p&gt;On a tous connu ce cas de figure, ou l'on doit déployer une application web sur une plateforme autre que celle sur laquelle on développe (serveur de dev, recette, prod etc...);&lt;br /&gt;A minima on se retrouve à modifier les chaines de connexions vers la/les bases de données, au mieux on a prévu une copie tweakée du web.config par plateforme (avec le gros inconvénient d'avoir maintenant plusieurs fichiers à maintenir en parallèle), on fait ça dans l'urgence et hop ça plante :p.&lt;br /&gt;Surement un petit bout de configuration non que l'on a oublié de reporté dans ce fichier de conf spécifique à l'environnement visé. Ça sent le vécu, tout ça !&lt;/p&gt;&lt;p&gt;Réjouissez-vous ce temps est révolu!&lt;/p&gt;&lt;p&gt;Dans Visual Studio 2010, il possible de mettre en œuvre des transformations sur les fichiers de configuration. L'idée est d'avoir un fichier web.config servant de base, puis pour chaque Configuration de Solution (Debug, Release, etc..) un fichier de transformation contient les modifications apportés vis à vis du fichier de base.&lt;/p&gt;&lt;p&gt;&lt;img src="http://fabrice.michellonet.free.fr/MyMemoryLeaks/Posts/37/solution.jpg"/&gt;&lt;/p&gt;&lt;p&gt;Si l'on ajoute deux Configurations de solutions, par exemple Recette et Prod, puis que l'on clique sur Add Config Transform deux nouveaux fichiers apparaissent Web.Recette.config &amp; Web.Prod.config&lt;/p&gt;&lt;p&gt;&lt;img src="http://fabrice.michellonet.free.fr/MyMemoryLeaks/Posts/37/configTranform.jpg"/&gt;&lt;/p&gt;&lt;p&gt;L'idée de ce billet n'est pas d'expliquer en détail la syntaxe de transformation bien expliquée sur &lt;a href="http://msdn.microsoft.com/en-us/library/dd465326.aspx"&gt;MSDN&lt;/a&gt;; mais afin de poursuivre l'exemple voici mon web.config initial&lt;/p&gt;&lt;pre class="brush:xml"&gt;
&lt;connectionStrings&gt;
    &lt;add name="appDBConn" connectionString="data source=(localhost);Integrated Security=SSPI;initial catalog=MyDb" providerName="System.Data.SqlClient" /&gt;
&lt;/connectionStrings&gt;
&lt;/pre&gt;&lt;p&gt;et la transformation pour l'environnement de recette :&lt;/p&gt;&lt;pre class="brush:xml"&gt;
&lt;connectionStrings&gt;
&lt;add name="appDBConn" connectionString="data source=SRV_RECETTE;Integrated Security=SSPI;initial catalog=MyDb" providerName="System.Data.SqlClient" xdt:Transform="SetAttributes" xdt:Locator="Match(name)"/&gt;
&lt;/connectionStrings&gt;
&lt;/pre&gt;&lt;p&gt;Bon maintenant la mauvaise nouvelle (haaa ? j'vous avais pas dit qu'il y avait une mauvaise nouvelle?), c'est que la transformation du fichier de config ne se fait pas lors du build.&lt;br /&gt;Malheureusement, elle n’a lieu que lorsqu'on utilise webDeploy.&lt;br /&gt;La bonne nouvelle? C’est qu'en trafiquant un peu le csproj on peut lancer la tache MSBuild en charge de la transformation.&lt;/p&gt;&lt;p&gt;&lt;img src="http://fabrice.michellonet.free.fr/MyMemoryLeaks/Posts/37/editProject.jpg"/&gt;&lt;/p&gt;&lt;p&gt;Allez tout en bas du fichier et modifiez-le comme suit : &lt;/p&gt;&lt;pre class="brush:xml"&gt;
&lt;Target Name="AfterBuild"&gt;
    &lt;MakeDir Directories="obj\$(ConfigurationName)" /&gt;
&lt;TransformXml Condition="Exists('obj\$(ConfigurationName)')" Source="Web.config" Transform="$(ProjectConfigTransformFileName)" Destination="obj\$(ConfigurationName)\Web.config" /&gt;
&lt;/Target&gt;
&lt;/pre&gt;&lt;p&gt;A partir de maintenant après chaque build le fichier web.config sera transformé et copié dans le répertoire obj/Nom_De_La_Config/web.config&lt;/p&gt;&lt;p&gt;Voilà, c'est tout pour ce soir, j’espère que cette astuce vous facilitera la vie lors de vos futurs déploiements.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1146316188254265608-8492476905843542405?l=mymemoryleaks.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mymemoryleaks.blogspot.com/feeds/8492476905843542405/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1146316188254265608&amp;postID=8492476905843542405' title='3 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1146316188254265608/posts/default/8492476905843542405'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1146316188254265608/posts/default/8492476905843542405'/><link rel='alternate' type='text/html' href='http://mymemoryleaks.blogspot.com/2011/02/transformations-webconfig-d-web.html' title='Transformations web.config d&amp;#39;une Web application.'/><author><name>Fabrice Michellonet</name><uri>http://www.blogger.com/profile/10201820062243684793</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_yYUu3sWKdtU/SE76j2im4AI/AAAAAAAACFA/OgO15yojzu8/S220/Fabrice_MICHELLONET.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1146316188254265608.post-5736814822113597342</id><published>2011-02-18T22:13:00.010+01:00</published><updated>2011-02-28T23:47:42.087+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ASP.NET MVC'/><title type='text'>MVC3 - Utiliser facilement le Datepicker de JQuery.</title><content type='html'>&lt;p&gt;Un des points apportant le plus de productivit&amp;eacute; dans le framework ASP.NET MVC est surement l'avènement des Display &amp;amp; Editor Templates.&lt;/p&gt;&lt;p&gt;Je m'explique si vous suivez les best practices et que vos vues ressemblent plus ou moins &amp;agrave; cela :&lt;/p&gt;&lt;pre class="brush:razor"&gt;
@model CustomMVCScaffolder.Models.Employee

@* This partial view defines form fields that will appear when creating and editing entities *@
&lt;div class="editor-label"&gt;
    @Html.LabelFor(model =&amp;gt; model.NationalIdNumber)&lt;/div&gt;
&lt;div class="editor-field"&gt;
    @Html.EditorFor(model =&amp;gt; model.NationalIdNumber)
    @Html.ValidationMessageFor(model =&amp;gt; model.NationalIdNumber)&lt;/div&gt;
&lt;div class="editor-label"&gt;
    @Html.LabelFor(model =&amp;gt; model.Login)&lt;/div&gt;
&lt;div class="editor-field"&gt;
    @Html.EditorFor(model =&amp;gt; model.Login)
    @Html.ValidationMessageFor(model =&amp;gt; model.Login)&lt;/div&gt;
&lt;div class="editor-label"&gt;
    @Html.LabelFor(model =&amp;gt; model.JobTitle)&lt;/div&gt;
&lt;div class="editor-field"&gt;
    @Html.EditorFor(model =&amp;gt; model.JobTitle)
    @Html.ValidationMessageFor(model =&amp;gt; model.JobTitle)&lt;/div&gt;
&lt;div class="editor-label"&gt;
    @Html.LabelFor(model =&amp;gt; model.BirthDate)&lt;/div&gt;
&lt;div class="editor-field"&gt;
    @Html.EditorFor(model =&amp;gt; model.BirthDate)
    @Html.ValidationMessageFor(model =&amp;gt; model.BirthDate)&lt;/div&gt;
&lt;div class="editor-label"&gt;
    @Html.LabelFor(model =&amp;gt; model.Maried)&lt;/div&gt;
&lt;div class="editor-field"&gt;
    @Html.EditorFor(model =&amp;gt; model.Maried)
    @Html.ValidationMessageFor(model =&amp;gt; model.Maried)&lt;/div&gt;
&lt;div class="editor-label"&gt;
    @Html.LabelFor(model =&amp;gt; model.Gender)&lt;/div&gt;
&lt;div class="editor-field"&gt;
    @Html.EditorFor(model =&amp;gt; model.Gender)
    @Html.ValidationMessageFor(model =&amp;gt; model.Gender)&lt;/div&gt;
&lt;div class="editor-label"&gt;
    @Html.LabelFor(model =&amp;gt; model.HireDate)&lt;/div&gt;
&lt;div class="editor-field"&gt;
    @Html.EditorFor(model =&amp;gt; model.HireDate)
    @Html.ValidationMessageFor(model =&amp;gt; model.HireDate)&lt;/div&gt;
&lt;/pre&gt;&lt;p&gt;alors au runtime, le framework choisira le composant graphique HTML (Input, select etc...) le plus adapt&amp;eacute; &amp;agrave; afficher les propriétés du model et ca sur toutes vos vues.&lt;/p&gt;&lt;p&gt;La bonne nouvelle, c'est que l'on peut cr&amp;eacute;er nous m&amp;ecirc;me des templates pour les nouveaux types et encore mieux modifier les templates li&amp;eacute;s aux types de base (int, string, DateTime etc..)&lt;/p&gt;&lt;p&gt;&lt;span style="text-decoration: underline;"&gt;&lt;strong&gt;Stop le blabla, place au Datepicker.&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;Ok, on commence par cr&amp;eacute;er dossier un EditorTemplates sous Views/Shared et on y place une nouvelle vue que l'on nommera DateTime.cshtml.&lt;/p&gt;&lt;p&gt;&lt;img src="http://fabrice.michellonet.free.fr/MyMemoryLeaks/Posts/36/sol_explo.jpg" alt="adding an editor" /&gt;&lt;/p&gt;&lt;pre class="brush:razor"&gt;
@using MVCTest
@model DateTime?

@Html.Datepicker("", Model.HasValue ? Model.Value.ToShortDateString() : string.Empty, 0)
&lt;/pre&gt;&lt;p&gt;Remarquez la simplicit&amp;eacute;, on ne fait qu'appeler une m&amp;eacute;thode d'extension (que nous allons &amp;eacute;tudier de suite) et on formatte tr&amp;egrave;s l&amp;eacute;g&amp;egrave;rement la date (ToShortDateString).&lt;/p&gt;&lt;p&gt;Rajoutons une classe dans notre projet comportant le code suivant :&lt;/p&gt;&lt;pre class="brush:csharp"&gt;
using System.Collections.Generic;
using System.Web.Mvc;

namespace MVCTest
{
    public static class JQueryHtmlHelpers
    {
        public static MvcHtmlString Datepicker(this HtmlHelper htmlHelper, string name, object value)
        {
            return System.Web.Mvc.Html.InputExtensions.TextBox(htmlHelper, name, value, new Dictionary { { "class", "datepicker" } });
        }
    }
}
&lt;/pre&gt;&lt;p&gt;Dans cette m&amp;eacute;thode d'extension, on se contente de demander le rendu d'une TextBox (input html) a laquelle on applique la class css datepicker.&lt;br /&gt;Vous l'aurez compris il ne nous reste plus qu'a &amp;eacute;crire un peu de JQuery dans la master page pour que toute les texbox du site ayant la class datepicker se transforment par magie en DatePicker.&lt;/p&gt;&lt;pre class="brush:js"&gt;
$(document).ready(function () {
    $(".datepicker").datepicker();
});
&lt;/pre&gt;&lt;p&gt;Voila ce que ça donne :&lt;/p&gt;&lt;p&gt;&lt;a href='http://fabrice.michellonet.free.fr/MyMemoryLeaks/Posts/36/Avant.jpg' dojotype='dojox.image.Lightbox' group='av_ap' title='Avant'&gt;&lt;img src='http://fabrice.michellonet.free.fr/MyMemoryLeaks/Posts/36/Avant_thumb.jpg' alt='Avant'/&gt;&lt;/a&gt;&amp;nbsp;&lt;a href='http://fabrice.michellonet.free.fr/MyMemoryLeaks/Posts/36/Apres.jpg' dojotype='dojox.image.Lightbox' group='av_ap' title='Apres'&gt;&lt;img src='http://fabrice.michellonet.free.fr/MyMemoryLeaks/Posts/36/Avant_thumb.jpg' alt='Apres'/&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Je vous laisse imaginer tous les widgets que l'on peut intégrer facilement!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1146316188254265608-5736814822113597342?l=mymemoryleaks.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mymemoryleaks.blogspot.com/feeds/5736814822113597342/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1146316188254265608&amp;postID=5736814822113597342' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1146316188254265608/posts/default/5736814822113597342'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1146316188254265608/posts/default/5736814822113597342'/><link rel='alternate' type='text/html' href='http://mymemoryleaks.blogspot.com/2011/02/mvc3-utiliser-facilement-le-datepicker.html' title='MVC3 - Utiliser facilement le Datepicker de JQuery.'/><author><name>Fabrice Michellonet</name><uri>http://www.blogger.com/profile/10201820062243684793</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_yYUu3sWKdtU/SE76j2im4AI/AAAAAAAACFA/OgO15yojzu8/S220/Fabrice_MICHELLONET.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1146316188254265608.post-72780912620664610</id><published>2011-01-20T00:18:00.003+01:00</published><updated>2011-01-20T14:39:34.402+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='SSAS'/><category scheme='http://www.blogger.com/atom/ns#' term='SSRS'/><title type='text'>Analysis Services Report Pack</title><content type='html'>&lt;p&gt;Avant-hier, mon client m'a demandé s'il était possible d'avoir une "cartographie" de sa base OLAP que nous sommes en train de construire. &lt;/p&gt;&lt;p&gt;Par cartographie, il entendait a minima avoir un listing de toutes les mesures, dimensions et niveaux existants. Ma première réaction fut de vérifier si &lt;a href="http://bidshelper.codeplex.com/"&gt;BIDS Helper&lt;/a&gt; n'avait pas ce genre de feature cachée dans un coin. Circulez rien à voir de très intéressant de ce côté-là!&lt;/p&gt;&lt;p&gt;Je me suis ensuite rué sur Google pour voir s'il n'y avait pas un SQL Server Report Pack comme celui qui était apparu pour SQL Server 2005, mais axé Analysis Services. Rien non plus en direct de chez Redmond.&lt;br /&gt;Par contre en creusant un peu je suis tombé sur l'excellent blog de la société &lt;a href="http://capstonebi.blogspot.com/"&gt;Capstone&lt;/a&gt; et leur superbe &lt;a href="http://capstonebi.blogspot.com/2009/11/analysis-services-2008-metadata-report.html"&gt;Analysis Services 2008 Metadata Report Pack&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Voici un aperçu du rendu des rapports Reporting Services mis à disposition : &lt;/p&gt;&lt;p&gt;&lt;a href='http://fabrice.michellonet.free.fr/MyMemoryLeaks/Posts/35/root.jpg' dojotype='dojox.image.Lightbox' group='Reports' title='Database'&gt;&lt;img src='http://fabrice.michellonet.free.fr/MyMemoryLeaks/Posts/35/root_thumb.jpg' alt='Database'/&gt;&lt;/a&gt; &lt;a href='http://fabrice.michellonet.free.fr/MyMemoryLeaks/Posts/35/Cube_Det.jpg' dojotype='dojox.image.Lightbox' group='Reports' title='Cube'&gt;&lt;img src='http://fabrice.michellonet.free.fr/MyMemoryLeaks/Posts/35/Cube_Det_thumb.jpg' alt='Cube'/&gt;&lt;/a&gt; &lt;a href='http://fabrice.michellonet.free.fr/MyMemoryLeaks/Posts/35/Dimension_Det.jpg' dojotype='dojox.image.Lightbox' group='Reports' title='Dimension'&gt;&lt;img src='http://fabrice.michellonet.free.fr/MyMemoryLeaks/Posts/35/Mining_Model_thumb.jpg' alt='Dimension'/&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Et pour faire plaisir à mon ami &lt;a href="http://fjehl.blogspot.com/"&gt;François&lt;/a&gt;, il y a même des infos sur le Data Mining : &lt;/p&gt;&lt;p&gt;&lt;a href='http://fabrice.michellonet.free.fr/MyMemoryLeaks/Posts/35/Mining_Model.jpg' dojotype='dojox.image.Lightbox' group='Reports' title='Mining Model'&gt;&lt;img src='http://fabrice.michellonet.free.fr/MyMemoryLeaks/Posts/35/Mining_Model_thumb.jpg' alt='Dimension'/&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Pour installer le pack il vous faudra créer un serveur lié dans SQL Server; Voici le script SQL a mettre en adéquation avec la configuration de votre machine : &lt;/p&gt;&lt;pre class="brush:sql"&gt;
EXEC master.dbo.sp_addlinkedserver @server = N'SSAS_METADATA', @srvproduct=N'SSAS', @provider=N'MSOLAP', @datasrc=N'localhost', @provstr=N'Provider=MSOLAP.4', @catalog=N'Adventure Works DW 2008R2'
EXEC master.dbo.sp_addlinkedsrvlogin @rmtsrvname=N'SSAS_METADATA',@useself=N'False',@locallogin=NULL,@rmtuser=NULL,@rmtpassword=NULL
&lt;/pre&gt;&lt;p&gt;Puis déployer les rapports sur Reporting Services.&lt;/p&gt;&lt;p&gt;Je me permets de reposter l'ensemble de la solution de &lt;a href="http://capstonebi.blogspot.com/2009/11/analysis-services-2008-metadata-report.html"&gt;Dan Meyers&lt;/a&gt; &lt;a href="http://fabrice.michellonet.free.fr/MyMemoryLeaks/Posts/35/Analysis%20Services%202008%20Metadata%20Report%20Pack.zip"&gt;ici&lt;/a&gt;; version dans laquelle j'ai corrigé les connexions en dur par une connexion vers le serveur lié.&lt;/p&gt;&lt;p&gt;En dehors de répondre au besoin ponctuel de mon client, je me dis que ces rapports pourraient très bien trouver leur place dans une documentation technique à réaliser en fin de projet.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1146316188254265608-72780912620664610?l=mymemoryleaks.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mymemoryleaks.blogspot.com/feeds/72780912620664610/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1146316188254265608&amp;postID=72780912620664610' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1146316188254265608/posts/default/72780912620664610'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1146316188254265608/posts/default/72780912620664610'/><link rel='alternate' type='text/html' href='http://mymemoryleaks.blogspot.com/2011/01/analysis-services-report-pack.html' title='Analysis Services Report Pack'/><author><name>Fabrice Michellonet</name><uri>http://www.blogger.com/profile/10201820062243684793</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_yYUu3sWKdtU/SE76j2im4AI/AAAAAAAACFA/OgO15yojzu8/S220/Fabrice_MICHELLONET.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1146316188254265608.post-5474396911224764744</id><published>2011-01-18T23:22:00.007+01:00</published><updated>2011-01-19T00:33:23.225+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='IIS'/><category scheme='http://www.blogger.com/atom/ns#' term='ASP.NET'/><title type='text'>Injection HTML à base d'HTTPModule</title><content type='html'>&lt;p&gt;Dernièrement j'ai &amp;eacute;chang&amp;eacute; avec mon Boss, J&amp;eacute;r&amp;ocirc;me, sur les possibilit&amp;eacute;s d'enrichir un site web non d&amp;eacute;vellop&amp;eacute; en .NET mais qui serait host&amp;eacute; dans IIS.&lt;br /&gt;On pourrait se mettre à apprendre le Python... mais voila on est un peu fain&amp;eacute;ant :)&lt;/p&gt;&lt;p&gt;Une des solutions que je lui ai propos&amp;eacute; &amp;eacute;tais de tirer parti du m&amp;eacute;canisme d'extensibilit&amp;eacute; du pipeline de IIS7 afin d'intervenir directement sur le code HTML renvoy&amp;eacute; au navigateur.&lt;/p&gt;&lt;p&gt;&lt;div align='center'&gt;&lt;img src="http://fc09.deviantart.net/fs49/f/2009/179/6/7/67d8d599f0b79628e410f38b21028f90.jpg" width="600" height="300" alt="Green Injection"/&gt;&lt;/div&gt;&lt;/p&gt;&lt;p&gt;Je me propose donc de présenter dans les grandes lignes comment mettre en place ce genre de solution.&lt;br /&gt;Pour illustrer mes propos simplement nous allons nous rajouter un div en fin de page, le div contenant l'heure du système.&lt;/p&gt;&lt;p&gt;On commence par créer notre HTTPModule et on répond à l'évenement BeginRequest : &lt;/p&gt;

&lt;pre class="brush:csharp"&gt;
using System;
using System.IO;
using System.Web;

namespace InjectorModule
{
    public class Injector : IHttpModule
    {
        private HttpApplication _application;

        public void Init(HttpApplication context)
        {
            context.BeginRequest += OnBeginRequest;
            _application = context;
        }

        private void OnBeginRequest(object sender, EventArgs e)
        {
            Stream filter = FilterFactory.GetFilter(_application);
            if (filter == null)
                return;

            _application.Response.Filter = filter;
        }

        public void Dispose() {}
    }
}
&lt;/pre&gt;
&lt;p&gt;On d&amp;eacute;l&amp;egrave;gue &amp;agrave; une factory le role de cr&amp;eacute;er ou non un filter en fonction de r&amp;egrave;gles qui ne sont pas connues par le Module.&lt;br /&gt;Le module reste ainsi une brique uniquement technique technique.&lt;/p&gt;&lt;p&gt;Passons &amp;agrave; la factory&lt;/p&gt;&lt;pre class="brush:csharp"&gt;
using System.IO;
using System.Web;

namespace InjectorModule
{
    internal static class FilterFactory
    {
        public static Stream GetFilter(HttpApplication application)
        {
            if (application == null || application.Response.ContentType == null)
                return null;

            if (application.Response.ContentType.ToUpperInvariant().Contains("HTML"))
                return new AppendDateTimeFilter(application.Response.Filter, application.Request.ContentEncoding);

            return null;
        }
    }
}
&lt;/pre&gt;&lt;p&gt;Ici pas de r&amp;egrave;gles m&amp;eacute;tiers compliqu&amp;eacute;es, on ajoute un Filter si le content type est de type HTML.&lt;/p&gt;&lt;p&gt;Et finalement voici l'impl&amp;eacute;mentation du Filter qui tranforme la r&amp;eacute;ponse envoy&amp;eacute;e aux navigateurs :&lt;/p&gt;&lt;pre class="brush:csharp"&gt;
using System;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;

namespace InjectorModule
{
    internal class AppendDateTimeFilter : Stream
    {

        private readonly Stream _inputStream;
        private readonly Encoding _encoding;
        private readonly StringBuilder _responseHtml;

        public AppendDateTimeFilter(Stream input, Encoding contentEncoding)
        {
            _inputStream = input;
            _encoding = contentEncoding;
            _responseHtml = new StringBuilder();
        }

        #region Filter overrides

        public override bool CanRead
        {
            get { return true; }
        }

        public override bool CanSeek
        {
            get { return true; }
        }

        public override bool CanWrite
        {
            get { return true; }
        }

        public override void Close()
        {
            _inputStream.Close();
        }

        public override void Flush()
        {
            _inputStream.Flush();
        }

        public override long Length
        {
            get { return 0; }
        }

        public override long Position { get; set; }

        public override long Seek(long offset, SeekOrigin origin)
        {
            return _inputStream.Seek(offset, origin);
        }

        public override void SetLength(long length)
        {
            _inputStream.SetLength(length);
        }

        public override int Read(byte[] buffer, int offset, int count)
        {
            return _inputStream.Read(buffer, offset, count);
        }
        #endregion

        public override void Write(byte[] buffer, int offset, int count)
        {
            try
            {
                string bufferContent = _encoding.GetString(buffer);

                // Wait for the closing tag
                Regex eof = new Regex("", RegexOptions.IgnoreCase);

                _responseHtml.Append(bufferContent);
                if (!eof.IsMatch(bufferContent))
                    return;

                // Transform the response and write it back out
                string finalHtml = _responseHtml
                                        .Replace("", string.Format(@"
&lt;div&gt;{0}&lt;/div&gt;

", DateTime.Now))
                                        .ToString();

                // Send.
                byte[] data = _encoding.GetBytes(finalHtml);
                _inputStream.Write(data, 0, data.Length);
            }
            catch (Exception) { }

        }

    }
}
&lt;/pre&gt;&lt;p&gt;Pour tester rien de plus simple, on compile l'assembly, on la place dans le dossier bin du site web que l'on veux trafiquer.&lt;br /&gt;Dans notre cas, nous avons aussi du cr&amp;eacute;er le dossier bin car non existant dans l'appli Web Python.&lt;br /&gt;Le fait de placer l'assembly dans un dossier bin, est une contrainte technique impos&amp;eacute;e par IIS; je n'ai pas trouv&amp;eacute; d'alternatives et a priorit il n'y a pas de configuration qui pourrait influer sur cette contrainte.&lt;br /&gt;Finalement dans le gestionnaire IIS, rendez vous dans la section Modules de votre application Web.&lt;br /&gt;En ouvrant la fenetre d'ajout de modules, votre assembly sera d&amp;eacute;sormais pr&amp;eacute;sente; S&amp;eacute;lectionnez la, et pointez votre navigateur sur ce dernier.&lt;/p&gt;&lt;p&gt;Tadam!!! l'heure s'affiche tout en bas :)&lt;/p&gt;&lt;p&gt;J'esperes que cette solutions vous ouvre de nouvelles possibilit&amp;eacute;s.&lt;/p&gt;&lt;p&gt;Un dernier mot pour vous conseiller l'excellente librairie &lt;a href="http://htmlagilitypack.codeplex.com/"&gt;htmlagilitypack&lt;/a&gt; qui vous donnera les moyens de parser facilement un document HTML, m&amp;ecirc;me malform&amp;eacute;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1146316188254265608-5474396911224764744?l=mymemoryleaks.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mymemoryleaks.blogspot.com/feeds/5474396911224764744/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1146316188254265608&amp;postID=5474396911224764744' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1146316188254265608/posts/default/5474396911224764744'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1146316188254265608/posts/default/5474396911224764744'/><link rel='alternate' type='text/html' href='http://mymemoryleaks.blogspot.com/2011/01/injection-html-base-d.html' title='Injection HTML à base d&amp;#39;HTTPModule'/><author><name>Fabrice Michellonet</name><uri>http://www.blogger.com/profile/10201820062243684793</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_yYUu3sWKdtU/SE76j2im4AI/AAAAAAAACFA/OgO15yojzu8/S220/Fabrice_MICHELLONET.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1146316188254265608.post-483606607216912621</id><published>2010-10-26T00:12:00.002+02:00</published><updated>2010-10-26T15:40:43.118+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='SQL'/><title type='text'>Identity ou UniqueIdentifier (Guid) ?</title><content type='html'>&lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;&lt;p&gt;Je dois être maudit ! Cela fait prés de 3 ans que sur tous les projets sur lesquels j’interviens, le sempiternel &lt;a href='http://fr.wikipedia.org/wiki/Troll_%28Internet%29'&gt;troll&lt;/a&gt; du &lt;u&gt;Identity vs Guid&lt;/u&gt; revient me hanter.&lt;/p&gt;

&lt;p/&gt;&lt;div align='center'&gt;&lt;img src='http://img145.imageshack.us/img145/9742/grandecart.jpg'/&gt;
&lt;/div&gt;&lt;p&gt;

&lt;/p&gt;&lt;p&gt;Non, non, non… je ne suis pas un ayatollah de la base de donnée… je n’ai rien contre les GUID ! Mais pourtant j’ai quand même du mal à comprendre pourquoi on a tendance à en coller partout, même quand ca n’a aucun sens… et ca j’ai vraiment du mal… &lt;/p&gt;

&lt;p&gt;&lt;b&gt;&lt;u&gt;Mettons notre casquette de dba (je sais… beurk !)&lt;/u&gt;&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;Le Guid c’est le mal (sauf pour la réplication ou l’on n’a pas le choix)… car :&lt;/p&gt;

&lt;p/&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;en production, on a vu plus simple que d’écrire des jointures sur des choses aussi imbitables, et anti-mémorisable que B2F62BF0-5CE0-408c-B749-F37D76AF5629.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Les perfs sont juste pourries par rapports à celles que l’on obtiendrait avec un int. J’en entends déjà plus d’un ricaner et prêt à me soutenir le contraire….Bien ! Rendez-vous sur ce &lt;a href='http://blog.developpez.com/sqlpro/p7436/langage-sql-norme/guid-versus-auto-increment-le-verdict/'&gt;benchmark&lt;/a&gt;, et prenez même 10 minutes pour lancer le test chez vous… c’est flagrant !Ce qui est étonnant, c’est qu’un grand nombre de développeurs, y compris des gens très brillant, passent à côté de ce point… certain m’ont déjà soutenu le contraire… au secours !&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;

&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;u&gt;Mettons notre casquette de développeur : &lt;/u&gt;&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;Le Guid c’est la meilleure invention depuis le garbage collector… ! Si si je fais mon &lt;a href='http://fr.wikipedia.org/wiki/Gloubi-boulga'&gt;gloubi-boulga&lt;/a&gt; et puis je referme le capot, ca marche à tout les coups… c’est génial le GUID.&lt;/p&gt;

&lt;p&gt;Dans une architecture en couche, je peux générer des Id dans ma couche client, associer des entités entre elles… puis :&lt;/p&gt;

&lt;p&gt;Si j’ai envie de les persister, pas de soucis et pas d’aller retour avec la le tiers de persistance (base de données), mes identifiants sont à coup sur uniques.&lt;/p&gt;

&lt;p&gt;Si j’ai envie d’annuler tout ce que j’ai fais, bah je cache méthodiquement tout sous le tapis (lisez : je laisse travailler le garbage collector).&lt;/p&gt;
&lt;p&gt;Tandis qu’un Int en tant qu’identifiant, qu’est ce que c’est embêtant…  je crée une entité sur mon client mais tant que je n’ai pas fait d’aller retour avec ma base de donnée, je n’ai aucun moyen de savoir son identifiant…&lt;/p&gt;
&lt;p&gt;Vous voulez associer un produit et sa catégorie de produit tout deux nouvellement crées ? Possible, mais on va devoir écrire un peu de code et faire des allers-retours avec la base.&lt;/p&gt;

&lt;p&gt;Bref… vu d’en haut l’identity c’est chiant… on est d’accord.&lt;/p&gt;

&lt;p&gt;PS : Pour ceux qui me diraient qu’on est pas obligé de faire des applications en couches séparées… bah…. ils ont raison, mais sur un projet un minimum important ca devient vite difficile à maintenir de tout coder dans la form (aussi bien web que win)… faut que vous jetiez un coup d’œil au &lt;a href='http://fr.wikipedia.org/wiki/TDD'&gt;TDD&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Voila, c’est la que commence à mon sens notre vrai travail. Il nous faut estimer les avantages et les inconvénients des deux approches, et faire un choix entre la performance pure de la base et grosso modo la vitesse de développement de l’application… en ces temps ou le mot d’agilité et dans la bouche de tous, le choix est vite fait…  Promis m’sieur y’a quelques temps j’arrivais encore à faire le grand écart…&lt;/p&gt;

&lt;p&gt;Bon tout ca c’est bien beau, mais alors quelqu’un pourrait m’expliquer pourquoi il m’arrive de tomber sur des bases qui sont truffées de GUID (seul type de donnée utilisé comme clé primaire des tables) lorsque celles-ci sont attaquées par une application en mode client-serveur ? Franchement, la, ca me dépasse !&lt;/p&gt;

&lt;p&gt;Bon, aller pour ceux qui ont réussi à me lire jusqu’ici, voici quelques liens supplémentaires sur le sujet :
&lt;/p&gt;&lt;p&gt;&lt;a href='http://www.sqlskills.com/BLOGS/KIMBERLY/post/GUIDs-as-PRIMARY-KEYs-andor-the-clustering-key.aspx'&gt;Les racines des problèmes que posent les GUID avec les index Clustered&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href='http://msdn.microsoft.com/en-us/library/ms189786%28SQL.90%29.aspx'&gt;la fonction SQL-SERVER NEWSEQUENTIALID()&lt;/a&gt; si on adore les GUID dans SQL et que l’on ne peut s’en passer.&lt;/p&gt;

&lt;p&gt;Et le meilleur pour la fin, je vous laisse réfléchir sur la phrase suivante trouvée dans la &lt;a href='http://msdn.microsoft.com/en-us/library/ms190215.aspx'&gt;MSDN &lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;&lt;p/&gt;&lt;p&gt;Consider using the IDENTITY property when global uniqueness is not required, or when having a serially incrementing key is preferred.&lt;/p&gt;&lt;p/&gt;&lt;/blockquote&gt;

&lt;p&gt;Evidemment, si certain d’entre vous on envie de troller sur le sujet… les commentaires sont fait pour ca :)&lt;/p&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1146316188254265608-483606607216912621?l=mymemoryleaks.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mymemoryleaks.blogspot.com/feeds/483606607216912621/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1146316188254265608&amp;postID=483606607216912621' title='3 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1146316188254265608/posts/default/483606607216912621'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1146316188254265608/posts/default/483606607216912621'/><link rel='alternate' type='text/html' href='http://mymemoryleaks.blogspot.com/2010/10/identity-ou-uniqueidentifier-guid.html' title='Identity ou UniqueIdentifier (Guid) ?'/><author><name>Fabrice Michellonet</name><uri>http://www.blogger.com/profile/10201820062243684793</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_yYUu3sWKdtU/SE76j2im4AI/AAAAAAAACFA/OgO15yojzu8/S220/Fabrice_MICHELLONET.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1146316188254265608.post-310183282094609834</id><published>2010-04-27T19:55:00.002+02:00</published><updated>2010-04-28T17:23:35.575+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Autre'/><title type='text'>JetBrains supporte l'Open Source</title><content type='html'>&lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;&lt;p&gt;Comme vous le savez sûrement, la version 5 de &lt;a href='http://www.jetbrains.com/resharper/index.html'&gt;Resharper&lt;/a&gt; est disponible depuis quelques temps, évidement pour supporter la version 2010 de Visual Studio; même si le produit est installable sur un Visual Studio 2008. Le but de ce post, n'est pas juste de vous annoncer la mise à dispo d'un soft et d'en faire la pub, c'est vraiment pas mon genre, et encore moins le but de ce blog.&lt;/p&gt;
&lt;p&gt;Bon retour en arrière de quelques mois, je tombe (presque) par hasard sur le page de licensing de Resharper (à l'époque version 4.5) et je me disais que ca serait sûrement un bon investissement; Après tout, un code écrit plus vite, et avec moins de bugs (&lt;a href='http://stackoverflow.com/questions/304258/access-to-modified-closure-2'&gt;Modified Closure&lt;/a&gt;), c'est bon pour mes clients, ma boite et puis pour moi aussi au final. Bref, plusieurs type de licences sont listées sur le site, dont une Licence Open Source &lt;b&gt;GRATUITE&lt;/b&gt;...&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;Ouarf ouarf ouaf, s'écrit mon côté pessimiste...&lt;/p&gt;&lt;p&gt;Ça c'est de la bonne pub gratuite.&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;J'approfondis un peu, il est dit qu'il faut présenter son projet Open Source, prouver sa participation dans le projet et une commission décidera si une licence gratuite sera attribuée etc...&lt;/p&gt;
&lt;blockquote&gt;Bon ok, en gros derrière dois y avoir une vieille boite mail que plus personne ne lit, et de toute façon ca m'étonnerait que les mecs aient le temps et l'envie de faire autre chose que coder pour leurs softs... alors de la à aller jeter un œil sur les projets Open Source soumis, puis faire une commission faudrait pas pousser quand même&lt;/blockquote&gt;
&lt;p&gt;Je vous l'accorde, ce jour la je devais être en mode Christophe... un peu beaucoup bougon! :) &lt;/p&gt;
&lt;p&gt;Bon, pas très grave tout ca, car très peu de temps après je démarre une nouvelle mission (mon client actuel), et il se trouve que Resharper fait partie du toolkit de tout les développeurs... Ouf, j'vais pouvoir faire illusion, et faire croire que je sais un peu programmer.&lt;/p&gt;
&lt;p&gt;Pas mal de temps passe, la question de l'acquisition de Resharper n'est plus trop d'actualité, jusqu'à ce que les betas de la version 5 ne commencent a être mise à dispo. Et puis lorsque la version finale sort, je ne peux m'empêcher de l'installer, pour 30 jours seulement en version demo... sniff.&lt;/p&gt;
&lt;p&gt;Alors, il y a moins d'une semaine, je me lance, et soumet à la fameuse commission mon pet projet actuel (&lt;a href='http://claymore.codeplex.com/'&gt;Claymore&lt;/a&gt;), sans trop de conviction. Et figurez vous qu'a peine 3 jours après (un dimanche exactement... bah oui les commissions de développeurs c'est en dehors des heures de travail) la bonne nouvelle tombe dans ma boite mail... j'ai le droit a une version Full de Resharper 5.0 pendant 1 an grâce à ce projet Open Source.&lt;/p&gt;
&lt;p&gt;Donc déjà, je vous demande pardon mesdames et messieurs de chez JetBrains d'avoir douté de votre parole. Merci de cet effort que vous consentez pour améliorer la qualité du code Open Source. Et puis, j'suis sur que mes clients actuels et futures vous remercieront aussi... j'ferais moins de bugs grâce a vous.&lt;/p&gt;
&lt;p&gt;Moralité, si vous avez un bout de code qui vaut le coup d'être mis à dispo des autres, et qui de toute façon ne vous rendra pas millionnaire, publiez-le, il vous permettra peut être d'avoir une licence gratuite de Resharper.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Update [28 Avril 2010] : &lt;/b&gt;Jérôme m'a fait remarquer que mon lien vers l'exemple de Modified Closure était erroné. C'est corrigé.&lt;/p&gt;
&lt;div align='center'&gt;&lt;img src='http://www.jetbrains.com/idea/../styles2/../img/banners/rs5_sb.png'/&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1146316188254265608-310183282094609834?l=mymemoryleaks.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mymemoryleaks.blogspot.com/feeds/310183282094609834/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1146316188254265608&amp;postID=310183282094609834' title='2 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1146316188254265608/posts/default/310183282094609834'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1146316188254265608/posts/default/310183282094609834'/><link rel='alternate' type='text/html' href='http://mymemoryleaks.blogspot.com/2010/04/jetbrains-supporte-l-source.html' title='JetBrains supporte l&amp;#39;Open Source'/><author><name>Fabrice Michellonet</name><uri>http://www.blogger.com/profile/10201820062243684793</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_yYUu3sWKdtU/SE76j2im4AI/AAAAAAAACFA/OgO15yojzu8/S220/Fabrice_MICHELLONET.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1146316188254265608.post-5133934878337889191</id><published>2010-04-23T00:22:00.001+02:00</published><updated>2010-04-23T00:42:08.183+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='CIL'/><title type='text'>Overriding et Shadowing de méthodes en IL.</title><content type='html'>&lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;&lt;p&gt;En ce moment je fais joujou avec les &lt;a href='http://msdn.microsoft.com/en-us/library/system.reflection.emit.opcodes_members.aspx'&gt;opcodes&lt;/a&gt; &lt;a href='http://fr.wikipedia.org/wiki/Common_Intermediate_Language'&gt;CIL&lt;/a&gt; qui se cachent sous notre bon vieux C#.&lt;/p&gt;
&lt;p&gt;En voulant surcharger et cacher (shadow) successivement deux propriétés hérités, j'ai remarqué que le compilo générait une suite de metadata assez déroutante. Prenons l'exemple suivant : &lt;/p&gt;
&lt;pre class='brush:csharp'&gt;public class BaseClass
    {
        public int Prop1 { get; set; }
        public virtual int Prop2 { get; set; }
        public virtual int Prop3 { get; set; }
    }

    public class DerivClass : BaseClass
    {
        public int Prop1 { get; set; }
        public new int Prop2 { get; set; }
        public new virtual int Prop3 { get; set; }
    }
&lt;/pre&gt;
&lt;p&gt;Du coté de la classe de base on obtient les metadata suivantes sur le getter :
&lt;/p&gt;&lt;p&gt;
non virtual : &lt;/p&gt;&lt;pre class='brush:csharp'&gt;.method public hidebysig specialname instance int32 get_Prop1() cil managed&lt;/pre&gt;
virtual     : &lt;pre class='brush:csharp'&gt;.method public hidebysig specialname newslot virtual instance int32 get_Prop2() cil managed&lt;/pre&gt;
remarquez l'utilisation conjointes des metadata virtual et newslot, je reviendrais dessus juste après.&lt;p&gt;

Côté classe dérivée on obtient cela : 
&lt;/p&gt;&lt;p&gt;
non virtual : &lt;/p&gt;&lt;pre class='brush:csharp'&gt;.method public hidebysig specialname instance int32 get_Prop1() cil managed&lt;/pre&gt;
new         : &lt;pre class='brush:csharp'&gt;.method public hidebysig specialname instance int32 get_Prop2() cil managed&lt;/pre&gt;
virtual new : &lt;pre class='brush:csharp'&gt;.method public hidebysig specialname newslot virtual instance int32 get_Prop3() cil managed&lt;/pre&gt;&lt;p&gt;
&lt;/p&gt;&lt;p&gt;
Oulaaa... c'est la que ca se corse!!
Dans la classe de base, comme je vous le faisait remarquer précédemment, le compilo utilise conjointement les metadata virtual et newslot. Logiquement, on aurait pu s'attendre a voir uniquement le virtual. 
&lt;/p&gt;&lt;p&gt;Dans la classe dérivée, le shadowing non virtuel &lt;/p&gt;&lt;pre class='brush:csharp'&gt;public new int Prop2 { get; set; }&lt;/pre&gt; produit des metadata token strictement identiques à une propriété normale; et le shadowing virtuel produit un IL identique à propriété virtuelle.
&lt;p/&gt;&lt;p&gt;De ces constatation on peut en déduire que : 
Le token newslot, ne suffit pas à affirmer qu'il s'agit d'une shadowing methode (le getter non-virtuel de la classe de base et le getter new de la classe dérivée ayant les mêmes metadata).&lt;/p&gt;&lt;p&gt;Par contre, si une méthode contient le token virtual mais pas le newslot, alors c'est qu'il s'agit a coup sur d'un overriding et pas un shadowing.&lt;/p&gt;&lt;p&gt;Par déduction, on peut donc penser que si une méthode n'est pas un overriding (le token newslot est présent), alors il n'y a shadowing que si la signature [type de retour, nom et paramètres de la méthode] de la méthode existe également dans la classe de base.&lt;/p&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1146316188254265608-5133934878337889191?l=mymemoryleaks.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mymemoryleaks.blogspot.com/feeds/5133934878337889191/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1146316188254265608&amp;postID=5133934878337889191' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1146316188254265608/posts/default/5133934878337889191'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1146316188254265608/posts/default/5133934878337889191'/><link rel='alternate' type='text/html' href='http://mymemoryleaks.blogspot.com/2010/04/overriding-et-shadowing-de-methodes-en.html' title='Overriding et Shadowing de méthodes en IL.'/><author><name>Fabrice Michellonet</name><uri>http://www.blogger.com/profile/10201820062243684793</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_yYUu3sWKdtU/SE76j2im4AI/AAAAAAAACFA/OgO15yojzu8/S220/Fabrice_MICHELLONET.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1146316188254265608.post-3318019944939466331</id><published>2010-04-21T23:37:00.001+02:00</published><updated>2010-04-21T23:39:10.855+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ASP.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='Claymore'/><title type='text'>Interagir avec les pages ASP.NET avant l'Init.</title><content type='html'>&lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;&lt;p&gt;Au cours du développement de &lt;a href='http://claymore.codeplex.com/'&gt;Claymore&lt;/a&gt;, pour la partie ASP.NET plus précisément, j'ai eu besoin de trouver un &lt;a href='http://fr.wikipedia.org/wiki/Hook_%28informatique%29'&gt;hook&lt;/a&gt; me donnant la possibilité d'interagir avec les pages avant les events que l'on trouve sur l'objet Page.&lt;/p&gt;&lt;p&gt;J'ai tout d'abord pensé tripatouiller dans le fichier Global.asax... sans finalement avoir trouvé ce que je souhaitais. Par contre, en fouillant un peu du côté des &lt;a href='http://msdn.microsoft.com/fr-fr/library/9b9dh535.aspx'&gt;HttpModule&lt;/a&gt; je suis arrivé à la solution suivante :&lt;/p&gt;
&lt;pre class='brush:csharp'&gt;
using System;
using System.Reflection;
using System.Web;
using System.Web.UI;

namespace Claymore.Web
{
    /// &amp;lt;summary&amp;gt;
    /// 
    /// &amp;lt;/summary&amp;gt;
    public class ClaymoreHttpModule : IHttpModule
    {
        #region Fields

        private HttpApplication _application;

        #endregion

        /// &amp;lt;summary&amp;gt;
        /// Initializes a module and prepares it to handle requests.
        /// &amp;lt;/summary&amp;gt;
        /// &amp;lt;param name="context"&amp;gt; &amp;lt;/param&amp;gt;An &amp;lt;see cref="T:System.Web.HttpApplication"/&amp;gt; that provides access to the methods, properties, and events common to all application objects within an ASP.NET application
        public void Init(HttpApplication context)
        {
            if(context == null)
                throw  new ArgumentNullException("context");

            _application = context;

            context.PostMapRequestHandler += onPostMapRequestHandler;
        }


        /// &amp;lt;summary&amp;gt;
        /// Disposes of the resources (other than memory) used by the module that implements &amp;lt;see cref="T:System.Web.IHttpModule"/&amp;gt;.
        /// &amp;lt;/summary&amp;gt;
        public void Dispose(){}

        /// &amp;lt;summary&amp;gt;
        /// Handle PostMapRequest event.
        /// &amp;lt;/summary&amp;gt;
        /// &amp;lt;param name="sender"&amp;gt; &amp;lt;/param&amp;gt;The sender.
        /// &amp;lt;param name="e"&amp;gt; &amp;lt;/param&amp;gt;The &amp;lt;see cref="System.EventArgs"/&amp;gt; instance containing the event data.
        private void onPostMapRequestHandler(object sender, EventArgs e)
        {
            Page pageHandler;
            if ((pageHandler = _application.Context.Handler as Page) != null)
                pageHandler.PreInit += HandlePreInit;
        }

        /// &amp;lt;summary&amp;gt;
        /// Handles the pre init event.
        /// &amp;lt;/summary&amp;gt;
        /// &amp;lt;param name="sender"&amp;gt; &amp;lt;/param&amp;gt;The sender.
        /// &amp;lt;param name="e"&amp;gt; &amp;lt;/param&amp;gt;The &amp;lt;see cref="System.EventArgs"/&amp;gt; instance containing the event data.
        protected virtual void HandlePreInit(object sender, EventArgs e)
        {
            Page page = sender as Page;
            if (page != null){
                // Et voila, on a un pointeur sur une page, et l'on peut interagir avec elle avant l'événement Init.
                // Ajouter du code ici.
            }
        }
    }
}
&lt;/pre&gt;

&lt;p&gt;L'un d'entre vous connaîtrait-il une solution équivalente à base de &lt;a href='http://msdn.microsoft.com/en-us/library/5c67a8bd%28VS.71%29.aspx'&gt;HttpHandler&lt;/a&gt; ou autre?&lt;/p&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1146316188254265608-3318019944939466331?l=mymemoryleaks.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mymemoryleaks.blogspot.com/feeds/3318019944939466331/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1146316188254265608&amp;postID=3318019944939466331' title='2 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1146316188254265608/posts/default/3318019944939466331'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1146316188254265608/posts/default/3318019944939466331'/><link rel='alternate' type='text/html' href='http://mymemoryleaks.blogspot.com/2010/04/interagir-avec-les-pages-aspnet-avant-l.html' title='Interagir avec les pages ASP.NET avant l&amp;#39;Init.'/><author><name>Fabrice Michellonet</name><uri>http://www.blogger.com/profile/10201820062243684793</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_yYUu3sWKdtU/SE76j2im4AI/AAAAAAAACFA/OgO15yojzu8/S220/Fabrice_MICHELLONET.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1146316188254265608.post-3467548966815323308</id><published>2010-04-05T23:15:00.001+02:00</published><updated>2010-04-05T23:29:51.776+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='WCF'/><title type='text'>Benchmark WCF vs ASMX, Remoting, WSE, Enterprise Services.</title><content type='html'>&lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;&lt;p&gt;Je relais assez peu souvent les infos glanées sur tel ou tel site, préférant vous montrer un peu de code :)&lt;/p&gt;&lt;p&gt;Ceci dit ce soir je fais une exception, en vous encourageant vivement a jeter un coup d'œil au &lt;a href='http://msdn.microsoft.com/en-us/library/bb310550.aspx'&gt;benchmark des technos de mise en réseau&lt;/a&gt; que nous, développeurs .NET, avons à notre dispositions.&lt;/p&gt;&lt;p&gt;Le bench, étudie de manière approfondie chaque techno, et la compare dans un scenario viable et réaliste de leurs utilisations.&lt;/p&gt;&lt;p&gt;Je ne peux m'empêcher de vous donner une idée de ce qu'il en ressort :&lt;/p&gt;&lt;blockquote&gt;To summarize the results, WCF is 25%—50% faster than ASP.NET Web Services, and approximately 25% faster than .NET Remoting. Comparison with .NET Enterprise Service is load dependant, as in one case WCF is nearly 100% faster but in another scenario it is nearly 25% slower. For WSE 2.0/3.0 implementations, migrating them to WCF will obviously provide the most significant performance gains of almost 4x.&lt;/blockquote&gt;
&lt;p&gt;Donc , lorsque vous entamerez un nouveau projet, sans contraintes techniques spécifiques sur la partie mise en réseau, il n'y a plus d'excuse... c'est WCF ou rien :p&lt;/p&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1146316188254265608-3467548966815323308?l=mymemoryleaks.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mymemoryleaks.blogspot.com/feeds/3467548966815323308/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1146316188254265608&amp;postID=3467548966815323308' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1146316188254265608/posts/default/3467548966815323308'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1146316188254265608/posts/default/3467548966815323308'/><link rel='alternate' type='text/html' href='http://mymemoryleaks.blogspot.com/2010/04/benchmark-wcf-vs-asmx-remoting-wse.html' title='Benchmark WCF vs ASMX, Remoting, WSE, Enterprise Services.'/><author><name>Fabrice Michellonet</name><uri>http://www.blogger.com/profile/10201820062243684793</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_yYUu3sWKdtU/SE76j2im4AI/AAAAAAAACFA/OgO15yojzu8/S220/Fabrice_MICHELLONET.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1146316188254265608.post-7008553822497889512</id><published>2010-03-31T22:37:00.001+02:00</published><updated>2010-03-31T22:37:59.235+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='MVP'/><category scheme='http://www.blogger.com/atom/ns#' term='Claymore'/><title type='text'>Version 1.1.0.0 de Claymore</title><content type='html'>&lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;&lt;p&gt;Suite à la &lt;a href='http://claymore.codeplex.com/Thread/View.aspx?ThreadId=205281'&gt;demande&lt;/a&gt; d'un utilisateur sur &lt;a href='http://claymore.codeplex.com'&gt;Codeplex&lt;/a&gt; de pouvoir utiliser Claymore avec le Compact Framework, j'ai ajouté cette feature dans la librairie; Plus précisément, il existe désormais une assembly qui vise spécifiquement cette version du Framework.&lt;/p&gt;&lt;p&gt;Les classes du Namespace &lt;a href='http://msdn.microsoft.com/en-us/library/2a1tyt9s%28v=VS.90%29.aspx'&gt;Configuration&lt;/a&gt; n'existant pas dans le Compact Framework, j'ai donc du ajouter une API permettant de configurer par code, le fonctionnement de la librairie, tout comme il est possible de le faire en passant par une configuration dans le fichier app.config ou web.config.&lt;/p&gt;&lt;p&gt;J'en ai profité pour designer l'API de configuration en suivant les conventions des &lt;a href='http://en.wikipedia.org/wiki/Fluent_interface'&gt;Fluent interfaces&lt;/a&gt;; Ce type d'écriture semblant être de plus en plus apprécié des développeurs que nous sommes.&lt;/p&gt;&lt;p&gt;Bon téléchargement, et n'hésitez pas à me dire ce que vous en pensez.&lt;/p&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1146316188254265608-7008553822497889512?l=mymemoryleaks.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mymemoryleaks.blogspot.com/feeds/7008553822497889512/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1146316188254265608&amp;postID=7008553822497889512' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1146316188254265608/posts/default/7008553822497889512'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1146316188254265608/posts/default/7008553822497889512'/><link rel='alternate' type='text/html' href='http://mymemoryleaks.blogspot.com/2010/03/version-1100-de-claymore.html' title='Version 1.1.0.0 de Claymore'/><author><name>Fabrice Michellonet</name><uri>http://www.blogger.com/profile/10201820062243684793</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_yYUu3sWKdtU/SE76j2im4AI/AAAAAAAACFA/OgO15yojzu8/S220/Fabrice_MICHELLONET.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1146316188254265608.post-6631070130298957797</id><published>2010-02-19T00:43:00.000+01:00</published><updated>2010-02-19T00:44:13.490+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='MVP'/><category scheme='http://www.blogger.com/atom/ns#' term='Claymore'/><title type='text'>Claymore - Framework MVP</title><content type='html'>&lt;p&gt;Non non non, vous ne rêvez pas... non non je ne suis pas mort!
Ça faisait bien longtemps que je n'avais pas eu et pas pris le temps de mettre à jour ce blog... Qui as dit que les enfants n'était pas chronophages? :)&lt;/p&gt;
&lt;p&gt;Depuis près de deux ans, les missions sur lesquelles j'interviens sont très souvent liées au développement Winform et malheureusement à chaque fois c'est le même constat; les forms et/ou usercontrol sont un joli mélange de code métier et de gestion d'interface graphique, sans parler des cas ou l'on retrouve même le code d'accès aux données fourré au beau milieu de ce jolie petit monde.&lt;/p&gt;
&lt;p&gt;Pourtant, cela fait bien longtemps que l'on connait les patterns &lt;a href="http://fr.wikipedia.org/wiki/Mod%C3%A8le-Vue-Contr%C3%B4leur"&gt;MVC&lt;/a&gt;, &lt;a href="http://en.wikipedia.org/wiki/Model_View_Presenter"&gt;MVP&lt;/a&gt; et depuis quelques temps le &lt;a href="http://en.wikipedia.org/wiki/MVVM"&gt;MVVM&lt;/a&gt; qui prend son essor avec &lt;a href="http://en.wikipedia.org/wiki/Windows_Presentation_Foundation%3EWPF%3C/a%3E%20et%20%3Ca%20href=" http:="" en.wikipedia.org="" wiki="" silverlight=""&gt;Silverlight&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;En demandant aux architectes ou Lead techniques de ces projets, ce qui avait justifié de ne pas appliquer un des ces patterns, la réponse est presque toujours la même :
L'implémentation de ces modèles dans les applications rallonge (parfois beaucoup) les temps de développement, demande des compétences un peu plus high level de la part des développeurs, et la montée en compétence sur les frameworks existants est parfois très lente.&lt;/p&gt;
&lt;p&gt;Entre nous, avant de pouvoir appréhender et amortir le temps d'apprentissage d'un framework comme &lt;a href="http://msdn.microsoft.com/en-us/library/aa480450.aspx"&gt;Smart Client - Composite UI Application Block&lt;/a&gt; de Microsoft, le projet à intérêt à s'étaler sur un an au minimum.&lt;/p&gt;
&lt;p&gt;Afin de rester impartial, je ne m'étendrais pas sur les autres framework MVP qui peuvent se trouver sur la toile.
&lt;/p&gt;&lt;p&gt;Bref, il me semblait qu'il serait intéressant d'avoir un framework MVP simple d'utilisation dans mon escarcelle pour les prochains projets.
J'ai donc commencé à écrire ça dans mon coin; Aujourd'hui &lt;a href="http://claymore.codeplex.com/"&gt;Claymore&lt;/a&gt; me semble assez mûre pour le mettre à disposition des autres, et je l'ai donc publié sur &lt;a href="http://claymore.codeplex.com/"&gt;codeplex&lt;/a&gt;. Évidemment, &lt;a href="http://claymore.codeplex.com/"&gt;Claymore&lt;/a&gt; fonctionne avec les projets Winform mais je n'ai pu m'empêcher d'ajouter aussi le support des projets ASP.NET.&lt;/p&gt;
&lt;p&gt;J'espère que ce framework saura vous aider à découpler les couches métiers des couches UI...&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1146316188254265608-6631070130298957797?l=mymemoryleaks.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mymemoryleaks.blogspot.com/feeds/6631070130298957797/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1146316188254265608&amp;postID=6631070130298957797' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1146316188254265608/posts/default/6631070130298957797'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1146316188254265608/posts/default/6631070130298957797'/><link rel='alternate' type='text/html' href='http://mymemoryleaks.blogspot.com/2010/02/claymore-framework-mvp.html' title='Claymore - Framework MVP'/><author><name>Fabrice Michellonet</name><uri>http://www.blogger.com/profile/10201820062243684793</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_yYUu3sWKdtU/SE76j2im4AI/AAAAAAAACFA/OgO15yojzu8/S220/Fabrice_MICHELLONET.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1146316188254265608.post-9209336605279329112</id><published>2009-08-03T09:43:00.007+02:00</published><updated>2009-08-03T17:28:42.432+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Visual Studio'/><title type='text'>Code source du framework .NET</title><content type='html'>&lt;p&gt;Cela fait plus d'un an et demi que le site &lt;a href='http://referencesource.microsoft.com/'&gt;Microsoft Reference Source Code Center&lt;/a&gt; à vu le jour. Rappelons que ce dernier à pour but de mettre à disposition le code source des assembly suivantes :
&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;Mscorlib.DLL&lt;/li&gt;
&lt;li&gt;System.DLL&lt;/li&gt;
&lt;li&gt;System.Data.DLL&lt;/li&gt;
&lt;li&gt;System.Drawing.DLL&lt;/li&gt;
&lt;li&gt;System.Web.DLL&lt;/li&gt;
&lt;li&gt;System.Web.Extensions.DLL&lt;/li&gt;
&lt;li&gt;System.Windows.Forms.DLL&lt;/li&gt;
&lt;li&gt;System.XML.DLL&lt;/li&gt;
&lt;li&gt;WPF (UIAutomation*.dll, System.Windows.DLL, System.Printing.DLL, System.Speech.DLL, WindowsBase.DLL, WindowsFormsIntegration.DLL, Presentation*.dll, et quelques autres...)&lt;/li&gt;
&lt;li&gt;Microsoft.VisualBasic.DLL&lt;/li&gt;&lt;/ul&gt;&lt;p/&gt;&lt;p&gt;Depuis lors Visual Studio 2008 à été mis à jour afin d'offrir la possibilité de debugger en direct les sources du framework .NET.
Pour ceux qui aurait loupé l'info au moment de la sortie (peut-être que l'info n'a  pas été assez bien relayée), voici un &lt;a href='http://blogs.msdn.com/sburke/archive/2008/01/16/configuring-visual-studio-to-debug-net-framework-source-code.aspx'&gt;tutoriel&lt;/a&gt; de Shawn Burke qui vous permettra de configurer votre IDE préféré.&lt;/p&gt;&lt;p&gt;Pour les utilisateurs de VS2005 ou bien des version Express de Visual Studio, alors &lt;a href='http://www.codeplex.com/NetMassDownloader'&gt;.NET Mass Downloader&lt;/a&gt; est l'outil qu'il vous faut car il vous permettra de remplir le cache de code source utilisé par l'IDE et en prime vous autorisera de travailler même lorsque vous n'êtes pas connecté à Internet.&lt;/p&gt;&lt;p&gt;Voila donc quelques cas ou vous pourrez vous permettre d'oublier &lt;a href='http://www.red-gate.com/products/reflector'&gt;Reflector&lt;/a&gt; :D.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1146316188254265608-9209336605279329112?l=mymemoryleaks.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mymemoryleaks.blogspot.com/feeds/9209336605279329112/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1146316188254265608&amp;postID=9209336605279329112' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1146316188254265608/posts/default/9209336605279329112'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1146316188254265608/posts/default/9209336605279329112'/><link rel='alternate' type='text/html' href='http://mymemoryleaks.blogspot.com/2009/08/code-source-du-framework-net.html' title='Code source du framework .NET'/><author><name>Fabrice Michellonet</name><uri>http://www.blogger.com/profile/10201820062243684793</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_yYUu3sWKdtU/SE76j2im4AI/AAAAAAAACFA/OgO15yojzu8/S220/Fabrice_MICHELLONET.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1146316188254265608.post-2039276419130551459</id><published>2009-07-22T22:56:00.007+02:00</published><updated>2009-07-23T16:16:36.099+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Autre'/><title type='text'>Nouveau skin.</title><content type='html'>&lt;p&gt;Voila! après quelques nuits plutôt courtes je suis heureux de mettre en ligne ce nouveau thème pour mon blog.&lt;/p&gt;&lt;p&gt;Certains lecteurs m'ayant dit que sur l'ancienne version la fonte était trop petite et sombre, j'ai essayé de trouver un compromis entre la mode du flashy qui sévit de plus en plus sur la toile et mon penchant pour le gothisme... Finalement, je suis reparti sur un autre concept... Bref, vos yeux devraient moins saigner si vous lisez ces lignes sur le blog directement. Quand à ceux qui trouvent que le blog a basculé dans le mode Hacker (comprenez fonte blanche sur fond noir) et bien il vous reste toujours &lt;a href='http://www.google.fr/reader'&gt;Google Reader&lt;/a&gt; :)&lt;/p&gt;&lt;p&gt;Il y a aussi quelques améliorations au menu : &lt;/p&gt;&lt;ul&gt;&lt;li&gt;Passage à la version 1.3.1 de dojo sur le CDN fournit par Google&lt;/li&gt;&lt;li&gt;Passage à la version 2.0.320 de SyntaxHighlighter&lt;/li&gt;&lt;li&gt;Mise en place d'un style pour les blockquote sans l'utilisation d'image; Cela ne fonctionne qu'avec les navigateurs de dernière génération.&lt;/li&gt;&lt;/ul&gt;J'espère que vous aimerez autant que j'ai pris de plaisir a le mettre en place.&lt;p/&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1146316188254265608-2039276419130551459?l=mymemoryleaks.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mymemoryleaks.blogspot.com/feeds/2039276419130551459/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1146316188254265608&amp;postID=2039276419130551459' title='2 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1146316188254265608/posts/default/2039276419130551459'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1146316188254265608/posts/default/2039276419130551459'/><link rel='alternate' type='text/html' href='http://mymemoryleaks.blogspot.com/2009/07/nouveau-skin.html' title='Nouveau skin.'/><author><name>Fabrice Michellonet</name><uri>http://www.blogger.com/profile/10201820062243684793</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_yYUu3sWKdtU/SE76j2im4AI/AAAAAAAACFA/OgO15yojzu8/S220/Fabrice_MICHELLONET.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1146316188254265608.post-6396288833466510716</id><published>2009-07-12T23:30:00.003+02:00</published><updated>2009-07-22T22:30:53.166+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='SMDBehavior'/><title type='text'>SMDBehavior 0.22</title><content type='html'>&lt;p&gt;Un billet rapide pour annoncer la release 0.2.2 de &lt;a href="http://smdbehavior.codeplex.com"&gt;SMDBehavior&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;Cette version fixe un bug qui causait un disfonctionnement lors de l'appel de Web Services en utilisant le verbe GET. Merci à Andrew Cave qui m'a gentillement remonté ce bug.&lt;/p&gt; &lt;p&gt;J'ajouterais également cette semaine quelques exemples supplémentaires.&lt;/p&gt; &lt;p&gt;Bon téléchargement :)&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1146316188254265608-6396288833466510716?l=mymemoryleaks.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mymemoryleaks.blogspot.com/feeds/6396288833466510716/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1146316188254265608&amp;postID=6396288833466510716' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1146316188254265608/posts/default/6396288833466510716'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1146316188254265608/posts/default/6396288833466510716'/><link rel='alternate' type='text/html' href='http://mymemoryleaks.blogspot.com/2009/07/smdbehavior-022_299.html' title='SMDBehavior 0.22'/><author><name>Fabrice Michellonet</name><uri>http://www.blogger.com/profile/10201820062243684793</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_yYUu3sWKdtU/SE76j2im4AI/AAAAAAAACFA/OgO15yojzu8/S220/Fabrice_MICHELLONET.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1146316188254265608.post-2870528730443193600</id><published>2009-07-07T10:42:00.003+02:00</published><updated>2009-07-22T22:30:53.151+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Subsonic'/><category scheme='http://www.blogger.com/atom/ns#' term='ORM'/><title type='text'>Subsonic 3.0</title><content type='html'>&lt;p&gt;Mon petit &lt;a href="http://fr.wikipedia.org/wiki/Mapping_objet-relationnel"&gt;ORM&lt;/a&gt; chouchou monte de version, et on le retrouve désormais en version 3.0 avec tout un tas de nouveautés.&lt;/p&gt; &lt;p&gt;Depuis la sortie de la version 2.2 en avril dernier, certain pensaient que le projet &lt;a href="http://subsonicproject.com/"&gt;Subsonic&lt;/a&gt; était mort; Rob Connerry ayant été embauché par Microsoft, et le manque de communication sur le site concernant l'avancement m'arrangeant rien.&lt;/p&gt; &lt;p&gt;Mais c'était sans compter sur Rob qui nous préparait dans sa cave une mouture qui n'a sans doute plus grand chose à voir avec la version 2.2.&lt;/p&gt; &lt;p&gt;En effet, ciao le langage à base d'expressions pointées pour requêter la base de données, qui par ailleurs faisait sans doute toute la force de Subsonic face aux autres ORM, et bienvenu à &lt;a href="http://www.google.com/url?sa=t&amp;source=web&amp;ct=res&amp;cd=3&amp;url=http%3A%2F%2Fmsdn.microsoft.com%2Fen-us%2Flibrary%2Fbb425822.aspx&amp;ei=1whTStC-CcrOjAer59CaCQ&amp;rct=j&amp;q=linq+to+sql&amp;usg=AFQjCNFrhiV6T04_mwwsqb-91MiEij7UhQ&amp;sig2=QthgmHwrJwQD3xMq8fP1zA"&gt;Linq to SQL&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;De plus le système de templating à complètement été réécrit lui aussi; Subsonic utilise désormais &lt;a href="http://www.google.com/url?sa=t&amp;source=web&amp;ct=res&amp;cd=7&amp;url=http%3A%2F%2Fmsdn.microsoft.com%2Fen-us%2Flibrary%2Fbb126445.aspx&amp;ei=8whTSsG_AoShjAfv9ZCfCQ&amp;rct=j&amp;q=T4&amp;usg=AFQjCNE1M5JOJ8xG01yL9yoLpnIKOKQQuQ&amp;sig2=UjXtgCec0FF-FM3X_71Byg"&gt;T4&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;&lt;b&gt;Alors que peut-on en penser?&lt;/b&gt;&lt;/p&gt; &lt;p&gt;Historiquement je ne suis pas fan de Linq to SQL, surement car je n'ai pas pris assez le temps de faire joujou avec, cela sera surement la bonne occasion. Ceci dit faudrait penser à dire à l'équipe de Linq que l'instruction Select c'est en début de requête que ca se place ;)&lt;/p&gt; &lt;p&gt;Qu'en a T4, ca c'est une vrai bonne grosse nouvelle c'est tout simplement la killer feature à mes yeux; Le système est assez simple a prendre en main, ouvert, et donne accès a l'ensemble des possibilités de la plateforme .NET&lt;/p&gt; &lt;p&gt;Au niveau des Templates fournis en standard, on retrouve le très bon, mais controversé pattern ActiveRecord, et le tout nouveau SimpleRepository pour les amateurs de &lt;a href="http://en.wikipedia.org/wiki/Plain_Old_CLR_Object"&gt;POCO&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;Finalement, on sent bien l'influence corporate de Microsoft tout de même dans les choix de techno, mais c'est surement le meilleur choix qui s'offrait à l'équipe en terme de pérennité.&lt;/p&gt; &lt;p&gt;Je tacherais de vous faire une présentation un peu plus technique de cette version 3 dans un prochain article.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1146316188254265608-2870528730443193600?l=mymemoryleaks.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mymemoryleaks.blogspot.com/feeds/2870528730443193600/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1146316188254265608&amp;postID=2870528730443193600' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1146316188254265608/posts/default/2870528730443193600'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1146316188254265608/posts/default/2870528730443193600'/><link rel='alternate' type='text/html' href='http://mymemoryleaks.blogspot.com/2009/07/subsonic-30_9012.html' title='Subsonic 3.0'/><author><name>Fabrice Michellonet</name><uri>http://www.blogger.com/profile/10201820062243684793</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_yYUu3sWKdtU/SE76j2im4AI/AAAAAAAACFA/OgO15yojzu8/S220/Fabrice_MICHELLONET.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1146316188254265608.post-5928805868898215724</id><published>2009-05-27T15:41:00.006+02:00</published><updated>2009-07-22T22:30:52.808+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='SSIS'/><title type='text'>[François Jehl] : Montée en charge, quelques conseils.</title><content type='html'>&lt;p&gt;Dans son billet &lt;a href="http://fjehl.blogspot.com/2009/05/ssis-montee-en-charge-quelques-conseils.html#links"&gt;[SSIS] Montée en charge, quelques conseils.&lt;/a&gt; François, nous propose quelques très bon conseils d'optimisation des packages SSIS.&lt;/p&gt; &lt;p&gt;Pour une fois qu'il ne parle pas de Data Mining (quelqu'un comprend ce qu'il raconte au moins sur le DMX), je vais me permettre d'intervenir/compléter sur un point. J'espère que ca ne te dérange pas François.&lt;p&gt; &lt;blockquote&gt; &lt;i&gt;&lt;a href="http://fjehl.blogspot.com/"&gt;François&lt;/a&gt; à dit :&lt;/i&gt; &lt;p&gt;... SSIS est optimisé en mémoire donc à vous de l'économiser! Déjà, sélectionnez uniquement les colonnes utiles...&lt;/p&gt; &lt;/blockquote&gt; &lt;p&gt;Dans les Data Flow Sources, il est effectivement conseillé de ne sélectionner que les colonnes qui seront effectivement utilisées par la suite. Cependant, dans la suite de votre flux de données, certaines transformations (ex : Derived Column, Data Conversion etc...) vont dupliquer les colonnes les premières ne servant vraisemblablement plus.&lt;/p&gt; &lt;p&gt;Une solution souvent mise en place afin d'enlever les colonnes inutiles, est d'utiliser la tache Union All. En supprimant les Output Column inutiles, on pense réduire à juste titre la mémoire utilisée. La pire solution, serait d'utiliser des taches synchrones aggregate ou sort pour supprimer ces mêmes colonnes.&lt;/p&gt; &lt;p&gt;Mais alors si je conviens que cela réduit bel et bien l'utilisation de la mémoire, pourquoi n'est tout de même pas une bonne idée? Tout simplement de par le fait que supprimer une colonne induit la copie des buffers du pipeline vers de nouveaux buffers. Et malheureusement l'expérience prouve que cette action de copie est bien trop couteuse en terme de cycle CPU pour contrebalancer la réduction de la mémoire utilisée.&lt;/p&gt; &lt;blockquote&gt; &lt;i&gt;&lt;a href="http://forums.microsoft.com/MSDN/showpost.aspx?postid=1582077&amp;siteid=1"&gt;Darren Green - 10 Mai 2007&lt;/a&gt; à dit :&lt;/i&gt; &lt;p&gt;Something that people, including me get a bit worried about, is the fact that you end up with these big wide buffers. The classic scenario is when you need to convert between string and Unicode string or visa versa. You end up duplicating all your columns, which seems really horrid. Well it may not be great, but the alternative is even worse. Data Conversion and Derived Column transforms can do the conversion, but are synchronous, so we have duplicate columns in effect. Would it be better to have a custom component that worked asynchronously, so you didn't end up with two columns for all your strings? The short answer is no. I wrote a test component, cunningly named DeUnicodeAsynchTestComponent, and simply put it was 2 - 2.5 times slower than a data conversion transform. The cost of copying data between buffers for the asynchronous nature is far more expensive than the extra baggage of the "duplicate" columns.&lt;/p&gt; &lt;/blockquote&gt; &lt;p&gt; Voila François, j'espère que cette petite précision intervention ne te dérangera pas trop... promis je te laisse tranquille tant que tu parle de Data Mining.... Quand à moi, je retourne à mon code C#. &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1146316188254265608-5928805868898215724?l=mymemoryleaks.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mymemoryleaks.blogspot.com/feeds/5928805868898215724/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1146316188254265608&amp;postID=5928805868898215724' title='2 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1146316188254265608/posts/default/5928805868898215724'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1146316188254265608/posts/default/5928805868898215724'/><link rel='alternate' type='text/html' href='http://mymemoryleaks.blogspot.com/2009/05/francois-jehl-montee-en-charge-quelques_4362.html' title='[François Jehl] : Montée en charge, quelques conseils.'/><author><name>Fabrice Michellonet</name><uri>http://www.blogger.com/profile/10201820062243684793</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_yYUu3sWKdtU/SE76j2im4AI/AAAAAAAACFA/OgO15yojzu8/S220/Fabrice_MICHELLONET.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1146316188254265608.post-2655831512273317870</id><published>2009-05-27T12:04:00.004+02:00</published><updated>2009-07-22T22:30:53.136+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Mono.Cecil'/><title type='text'>Mono.Cecil : la reflexion sous stéroïdes.</title><content type='html'>&lt;p&gt;Dernièrement en étudiant les possibilités offertes par &lt;a href='http://msdn.microsoft.com/en-us/library/bb126445.aspx'&gt;T4&lt;/a&gt; (un prochain billet y sera consacré), j'ai été confronté une fois de plus a un problème bien connu de la Refection : L'impossibilité de décharger un assembly de l'AppDomain l'ayant chargé; La seule solution étant de décharger tout l'AppDomain.&lt;/p&gt; &lt;p&gt;Dans mon cas, l'AppDomain chargeant l'assembly était hosté par Visual Studio, ma seule solution était donc de fermer Visual Studio 2008... sniff sniff un peu violent!&lt;/p&gt; &lt;p&gt;En fouillant mes bookmarks non traités, je retombe sur &lt;a href='http://www.mono-project.com/Cecil'&gt;Mono.Cecil&lt;/a&gt;, un Framework d'introspection écrit par &lt;a href='http://evain.net/blog/'&gt;Jean-Baptiste Evain&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;Qu'est ce que Mono.Cecil? Je dirais que c'est de la reflexion sous stéroïde car non soumis aux mêmes limitations que la reflexion, et qu'en prime on peut aussi créer/modifier du code CIL avec.&lt;/p&gt; &lt;p&gt;Alors comment choisir entre les deux ? Je vous laisse découvrir l'excellent article &lt;a href='http://codebetter.com/blogs/patricksmacchia/archive/2008/03/18/mono-cecil-vs-system-reflection.aspx'&gt;Mono.Cecil vs. System.Reflection&lt;/a&gt; de &lt;a href='http://codebetter.com/blogs/patricksmacchia/default.aspx'&gt;Patrick Smacchia&lt;/a&gt; un des auteurs de &lt;a href='http://www.ndepend.com/'&gt;NDepend&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Pour ne pas déroger à la règle un petit bout de code afin de mettre le pied a l'étrier.&lt;pre class='brush:csharp'&gt;&lt;br /&gt;AssemblyDefinition myLibrary = AssemblyFactory.GetAssembly("MyLibrary.dll");&lt;br /&gt;&lt;br /&gt;foreach (TypeDefinition typeDef in myLibrary.MainModule.Types){&lt;br /&gt;  if (!typeDef.IsClass)&lt;br /&gt;    continue;&lt;br /&gt;&lt;br /&gt;  Console.WriteLine(typeDef.FullName);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/p&gt; &lt;p&gt;Bonne introspection.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1146316188254265608-2655831512273317870?l=mymemoryleaks.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mymemoryleaks.blogspot.com/feeds/2655831512273317870/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1146316188254265608&amp;postID=2655831512273317870' title='3 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1146316188254265608/posts/default/2655831512273317870'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1146316188254265608/posts/default/2655831512273317870'/><link rel='alternate' type='text/html' href='http://mymemoryleaks.blogspot.com/2009/05/monocecil-la-reflexion-sous-steroides_2256.html' title='Mono.Cecil : la reflexion sous stéroïdes.'/><author><name>Fabrice Michellonet</name><uri>http://www.blogger.com/profile/10201820062243684793</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_yYUu3sWKdtU/SE76j2im4AI/AAAAAAAACFA/OgO15yojzu8/S220/Fabrice_MICHELLONET.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1146316188254265608.post-6202549526778474739</id><published>2009-05-08T23:02:00.004+02:00</published><updated>2009-07-22T22:30:53.124+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='SMDBehavior'/><category scheme='http://www.blogger.com/atom/ns#' term='WCF'/><title type='text'>SMDBehavior</title><content type='html'>&lt;p&gt;Lors des deux derniers billets, je vous ai présenté les possibilités offertes par le format &lt;a href='http://groups.google.com/group/json-schema?lnk=srg'&gt;SMD&lt;/a&gt; (simple method description) qui n'est autre qu'un JSON permettant de décrire un service web tout comme wsdl le fait en xml.&lt;/p&gt; &lt;p&gt;Pour rappel, certain Framework Ajax comme &lt;a href='www.dojotoolkit.org/'&gt;Dojo&lt;/a&gt; et &lt;a href='http://developer.yahoo.com/yui/'&gt;Yahoo UI&lt;/a&gt;, savent interpréter ce JSON et généré automatiquement la classe proxy qui permettra de travailler facilement en Javascript avec les WebService.&lt;/p&gt; &lt;p&gt;Bref, tout ca pour vous annoncer que j'ai dernièrement travaillé sur une extension &lt;a href='http://msdn.microsoft.com/en-us/netframework/aa663324.aspx'&gt;WCF&lt;/a&gt; qui génére automatiquement le SMD de vos services; et que le fruit de ce travail est disponible sur &lt;a href='http://www.codeplex.com/'&gt;Codeplex&lt;/a&gt; à l'adresse suivante : &lt;a href='http://smdbehavior.codeplex.com/'&gt;SMDBehavior&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;Evidemment, pas besoin de modifier vos services, il suffit d'ajouter quelques lignes de configuration dans le fichier web.config ou app.config pour que cela fonctionne.&lt;/p&gt; &lt;p&gt;Sur le site du projet &lt;a href='http://smdbehavior.codeplex.com/'&gt;SMDBehavior&lt;/a&gt; vous pourrez télécharger le binaire, une solution de démo et si vous avez un identifiant Codeplex, vous pourrez aussi obtenir les sources. Je ne m'étendrais pas ce soir sur la mise en oeuvre de cette extension WCF, car tout est explique sur la page &lt;a href='http://smdbehavior.codeplex.com/'&gt;SMDBehavior&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Happy SMD.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1146316188254265608-6202549526778474739?l=mymemoryleaks.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mymemoryleaks.blogspot.com/feeds/6202549526778474739/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1146316188254265608&amp;postID=6202549526778474739' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1146316188254265608/posts/default/6202549526778474739'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1146316188254265608/posts/default/6202549526778474739'/><link rel='alternate' type='text/html' href='http://mymemoryleaks.blogspot.com/2009/05/smdbehavior_9898.html' title='SMDBehavior'/><author><name>Fabrice Michellonet</name><uri>http://www.blogger.com/profile/10201820062243684793</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_yYUu3sWKdtU/SE76j2im4AI/AAAAAAAACFA/OgO15yojzu8/S220/Fabrice_MICHELLONET.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1146316188254265608.post-5815076979259612615</id><published>2009-04-20T14:30:00.010+02:00</published><updated>2009-07-22T22:30:53.109+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Dojo'/><category scheme='http://www.blogger.com/atom/ns#' term='WCF'/><title type='text'>Dojo + WCF [2eme Partie]</title><content type='html'>&lt;p&gt;Dans le &lt;a href='http://mymemoryleaks.blogspot.com/2009/04/dojo-wcf-1ere-partie.html'&gt;précèdent billet&lt;/a&gt;, je vous avais proposé d’invoquer un service WCF en utilisant les XmlHttpRequest à la sauce dojo (&lt;a href='http://api.dojotoolkit.org/jsdoc/dojo.xhrGet'&gt;xhrGet&lt;/a&gt; et &lt;a href='http://api.dojotoolkit.org/jsdoc/1.3/dojo.xhrPost'&gt;xhrPost&lt;/a&gt;).&lt;/p&gt; &lt;p&gt;Bien que cette façon de faire soit bien plus rapide et « élégante » que lorsqu’on doit écrire soit même ce type de code js (avec support des navigateurs browser etc…), il existe une méthode encore plus simple.&lt;/p&gt; &lt;p&gt;Bien, revenons quelques instants sur les services web publiés aussi bien sous forme d’&lt;a href='http://en.wikipedia.org/wiki/ASP.NET'&gt;ASMX&lt;/a&gt; qu'en &lt;a href='http://msdn.microsoft.com/en-us/netframework/aa663324.aspx'&gt;WCF&lt;/a&gt;, ils ont la bonne idée d’être accompagnés d’une nomenclature les décrivants ; Vous l’aurez compris je parle bien ici du &lt;a href='http://www.w3.org/TR/wsdl'&gt;wsdl&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;L’intérêt majeur que je vois dans le wsdl est que cela permet de générer automatiquement un proxy qui saura communiquer avec le service web ciblé. D’ailleurs, c’est grâce à cette description que visual studio génère la classe proxy lorsque vous ajoutez une référence web dans votre solution.&lt;/p&gt; &lt;p&gt;L’idée derrière les classes du namespace &lt;a href='http://docs.dojocampus.org/dojox/rpc/Service'&gt;dojox.rpc&lt;/a&gt; est d’avoir ce même comportement en JavaScript, c'est-à-dire, la possibilité d’interroger un service pour connaitre ses caractéristiques et de générer automatiquement un proxy JavaScript simplifiant son utilisation.&lt;/p&gt; &lt;p&gt;Excellent me direz-vous, nous avons déjà le wsdl... arf c’est la que le bas blesse, le &lt;a href='http://www.w3.org/XML/'&gt;xml&lt;/a&gt; (et plus spéciale une définition wsdl) n’a jamais été le format le plus simple et le plus rapide à traiter en JavaScript. Par contre, comme vous le savez déjà le &lt;a href='http://www.json.org/'&gt;json&lt;/a&gt; est le format fétiche du web.&lt;/p&gt; &lt;p&gt;C’est donc à partir d’une définition en json respectant le formalisme nommé &lt;a href="http://groups.google.com/group/json-schema/web/service-mapping-description-proposal"&gt;smd&lt;/a&gt; (pour Simple Method Description) que le Framework dojo va vous permettre de générer le proxy JavaScript qui correspondra à votre service web.&lt;/p&gt; &lt;p&gt;Bien trêve de discussion adaptons notre précédent exemple pour l’adapter a cette technique de génération de proxy. Créons la définition du service : &lt;/p&gt;&lt;pre class='brush:jscript'&gt;&lt;br /&gt;{&lt;br /&gt;    "transport": "POST",&lt;br /&gt;    "envelope": "URL",&lt;br /&gt;    "target": "http://localhost/WCFDojoRpc/ClockService.svc/",&lt;br /&gt;    "services": {&lt;br /&gt;        "GetTime": {&lt;br /&gt;            "transport": "GET",&lt;br /&gt;            "target": "GetTime",&lt;br /&gt;            "parameters": []&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;p&gt; On y retrouve facilement les informations relatives a l’adresse du service et la méthode disponible. Pour plus de détail, je vous laisse vous reporter au &lt;a href="http://groups.google.com/group/json-schema/web/service-mapping-description-proposal"&gt;groupe de travail qui s’intéresse au format smd.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Modifions quelque peu notre script :&lt;/p&gt;&lt;pre class='brush:html' name='code'&gt;&lt;br /&gt;&amp;lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&amp;gt;&lt;br /&gt;&amp;lt;html xmlns="http://www.w3.org/1999/xhtml"&amp;gt;&lt;br /&gt;&amp;lt;head&amp;gt;&lt;br /&gt;    &amp;lt;title&amp;gt;Dojo &amp;amp; WCF&amp;lt;/title&amp;gt;&lt;br /&gt;&lt;br /&gt;    &amp;lt;script src="http://ajax.googleapis.com/ajax/libs/dojo/1.3.0/dojo/dojo.xd.js" type="text/javascript"&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;&lt;br /&gt;    &amp;lt;script type="text/javascript"&amp;gt;&lt;br /&gt;        dojo.require('dojo.parser');&lt;br /&gt;        dojo.require("dojox.rpc.Service");&lt;br /&gt;&lt;br /&gt;        var clockProxy;&lt;br /&gt;&lt;br /&gt;        dojo.addOnLoad(&lt;br /&gt;            function() {&lt;br /&gt;                clockProxy = new dojox.rpc.Service("definition.json");&lt;br /&gt;                GetTime();&lt;br /&gt;            }&lt;br /&gt;        );&lt;br /&gt;&lt;br /&gt;        function GetTime() {&lt;br /&gt;            clockProxy.GetTime()&lt;br /&gt;                .addCallback(&lt;br /&gt;                    function(data) {&lt;br /&gt;                        dojo.byId('ServerTime').innerHTML = data.d;&lt;br /&gt;                    }&lt;br /&gt;                )&lt;br /&gt;                .addErrback(&lt;br /&gt;                    function(data) {&lt;br /&gt;                        alert(data);&lt;br /&gt;                    }&lt;br /&gt;                );&lt;br /&gt;        }    &lt;br /&gt;        &lt;br /&gt;    &amp;lt;/script&amp;gt;&lt;br /&gt;&amp;lt;/head&amp;gt;&lt;br /&gt;&amp;lt;body&amp;gt;&lt;br /&gt;    &amp;lt;input type="button" value="Time?" onclick="GetTime();" /&amp;gt;&lt;br /&gt;    &amp;lt;div id="ServerTime"&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;&amp;lt;/body&amp;gt;&lt;br /&gt;&amp;lt;/html&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;Comme vous le voyez nous avons principalement retiré l’utilisation des xhrPost, que nous avons remplacés par une simple ligne new dojox.rpc.Service("definition.json"); qui génère le proxy JavaScript automatiquement a partir de la définition en json.&lt;/p&gt; &lt;p&gt;Bien évidement le service WCF reste identique a celui présenté dans la première partie de cet article.&lt;/p&gt; &lt;p&gt;Je retire deux conclusions partielles de l’utilisation des smd : &lt;ul&gt; &lt;li&gt;Il est certain que la possibilité de décrire un service facilite ensuite la vie du développeur coté js.&lt;/li&gt; &lt;li&gt;Il est dommage de devoir utiliser autre chose que le wsdl qui est généré pour nous, surtout lorsqu’on est un développeur .NET.&lt;/li&gt; &lt;/ul&gt; &lt;/p&gt; &lt;p&gt;Le top serait d’avoir une description smd générée automatiquement à chaque modification de notre service WCF et que ce soit intégré dans le pipeline WCF. C’est ce que je me propose de vous montrer lors de la troisième partie de cet article.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1146316188254265608-5815076979259612615?l=mymemoryleaks.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mymemoryleaks.blogspot.com/feeds/5815076979259612615/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1146316188254265608&amp;postID=5815076979259612615' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1146316188254265608/posts/default/5815076979259612615'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1146316188254265608/posts/default/5815076979259612615'/><link rel='alternate' type='text/html' href='http://mymemoryleaks.blogspot.com/2009/04/dojo-wcf-2eme-partie_2604.html' title='Dojo + WCF [2eme Partie]'/><author><name>Fabrice Michellonet</name><uri>http://www.blogger.com/profile/10201820062243684793</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_yYUu3sWKdtU/SE76j2im4AI/AAAAAAAACFA/OgO15yojzu8/S220/Fabrice_MICHELLONET.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1146316188254265608.post-1045942312129307472</id><published>2009-04-08T22:01:00.012+02:00</published><updated>2009-07-22T22:30:53.088+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Dojo'/><category scheme='http://www.blogger.com/atom/ns#' term='WCF'/><title type='text'>Dojo + WCF [1ere Partie]</title><content type='html'>&lt;p&gt;Voila déjà plusieurs mois, j’avais une discussion sur les architectures SOA avec Christophe et surtout comment les mettre en œuvre avec les Framework (Ajax) Javascript. A l’époque il démarrait une refonte de sa galerie de photos perso &lt;a href='http://lccfamily.net/'&gt;LCCFamilly&lt;/a&gt; et souhaitait qu’elle soit Full Ajax.&lt;/p&gt; &lt;p&gt;Sur ce même principe, je me propose aujourd’hui de vous montrer comment interroger un WebService &lt;a href='http://msdn.microsoft.com/fr-fr/netframework/aa663324.aspx'&gt;WCF&lt;/a&gt; à partir du Framework &lt;a href='http://www.dojotoolkit.org/'&gt;Dojo&lt;/a&gt; ; Faisons un service qui nous donne l’heure et la date courante formatée selon la locale du serveur. On commence par déclarer l’interface de notre service.&lt;/p&gt;&lt;pre class='brush:csharp'&gt;&lt;br /&gt;[ServiceContract(Namespace="http://www.devolis.com/2009/04/WCFDOJO")]&lt;br /&gt;    public interface IClockService&lt;br /&gt;    {&lt;br /&gt;        [OperationContract]&lt;br /&gt;        [WebInvoke(Method = "POST")]&lt;br /&gt;        string GetTime();&lt;br /&gt;    }&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;Notez l’utilisation du verbe POST ; Il convient d’éviter le verbe GET comme la peste si vous utilisez Internet Explorer comme client de votre WebService. En effet, sa gestion du cache, fait qu’il n’effectue que le premier appel, puis se contente de renvoyer ce qu’il a en cache.&lt;/p&gt; &lt;p&gt;Puis passons à l’implémentation à proprement dit du service&lt;/p&gt;&lt;pre class="brush:csharp"&gt;&lt;br /&gt;/// AspNetCompatibilityRequirements n'est utile que si le webservice est hosté dans IIS&lt;br /&gt;    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]&lt;br /&gt;    public class ClockService : IClockService&lt;br /&gt;    { &lt;br /&gt;        public string GetTime()&lt;br /&gt;        {&lt;br /&gt;            return DateTime.Now.ToString();&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;/pre&gt; &lt;p&gt;Ok, a ce moment précis, il vous est déjà possible de tester le WebService en créant rapidement un projet console et en ajoutant une WebReference sur ce dernier... Je vous laisse le faire de votre coté :)&lt;/p&gt; &lt;p&gt;Passons à notre page web :&lt;/p&gt;&lt;pre class="brush:html"&gt;&lt;br /&gt;&amp;lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&amp;gt;&lt;br /&gt;&amp;lt;html xmlns="http://www.w3.org/1999/xhtml" &amp;gt;&lt;br /&gt;&amp;lt;head&amp;gt;&lt;br /&gt;    &amp;lt;title&amp;gt;Dojo &amp;amp; WCF&amp;lt;/title&amp;gt;&lt;br /&gt;    &amp;lt;script src="http://ajax.googleapis.com/ajax/libs/dojo/1.3.0/dojo/dojo.xd.js" type="text/javascript"&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;    &lt;br /&gt;    &lt;br /&gt;    &amp;lt;script type="text/javascript"&amp;gt;&lt;br /&gt;        dojo.require('dojo.parser');&lt;br /&gt;    &amp;lt;/script&amp;gt;&lt;br /&gt;    &lt;br /&gt;    &amp;lt;script type="text/javascript"&amp;gt;&lt;br /&gt;&lt;br /&gt;        function GetTime() {&lt;br /&gt;            dojo.xhrPost({&lt;br /&gt;                url: "ClockService.svc/GetTime",&lt;br /&gt;                handleAs: "text",&lt;br /&gt;                contentType: "application/json; charset=utf-8",&lt;br /&gt;                load: function(response, ioArgs) {&lt;br /&gt;                    dojo.byId('ServerTime').innerHTML = dojo.fromJson(response).d;&lt;br /&gt;                    return response;&lt;br /&gt;                },&lt;br /&gt;                error: function(response, ioArgs) {&lt;br /&gt;                    alert("Error :" + ioArgs.xhr.status);&lt;br /&gt;                    return response;&lt;br /&gt;                }&lt;br /&gt;            });&lt;br /&gt;        }&lt;br /&gt;        &lt;br /&gt;    &amp;lt;/script&amp;gt;&lt;br /&gt;&amp;lt;/head&amp;gt;&lt;br /&gt;&amp;lt;body onload="GetTime();"&amp;gt;&lt;br /&gt;    &amp;lt;input type="button" value="Time?"  onclick="GetTime();" ///&amp;gt;&lt;br /&gt;    &amp;lt;div id="ServerTime"&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;&amp;lt;/body&amp;gt;&lt;br /&gt;&amp;lt;/html&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;Comme vous pouvez le constater, le code est assez concis. Apres avoir déclaré l’utilisation de Dojo 1.3 à partir du CDN de &lt;a href="http://code.google.com/intl/fr/apis/ajaxlibs/documentation/"&gt;Google&lt;/a&gt;, j’ai déclaré une fonction GetTime() qui par le biais d’un &lt;a href="http://fr.wikipedia.org/wiki/XMLHttpRequest"&gt;XmlHttpRequest&lt;/a&gt; (xhr) va demander au WebService de lui retourner le DateTime actuel ; les données sont attendues sous forme de &lt;a href="http://fr.wikipedia.org/wiki/JavaScript_Object_Notation"&gt;JSon&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;Vous remarquerez aussi la construction de l’url d’appel, il s’agit du nom du Service suivit par le nom de la méthode.&lt;/p&gt; &lt;p&gt;Si vous exécutez maintenant la page web, vous recevrez une erreur http 405. En effet pour l’instant Dojo et WCF ne parlent pas encore la même langue. Dojo parle en JSon et WCF en &lt;a href="http://fr.wikipedia.org/wiki/SOAP"&gt;Soap&lt;/a&gt;... il va nous falloir configurer le service.&lt;/p&gt; &lt;p&gt;Voici la globalité du ServiceModel que vous trouverez dans votre web.config ou app.config en fonction du type de projet choisit.&lt;/p&gt;&lt;pre class="brush:xml"&gt;&lt;br /&gt;&amp;lt;system.serviceModel&amp;gt;&lt;br /&gt;    &lt;br /&gt;    &amp;lt;behaviors&amp;gt;&lt;br /&gt;      &amp;lt;serviceBehaviors&amp;gt;&lt;br /&gt;        &amp;lt;behavior name="MetaDataBehavior" &amp;gt;&lt;br /&gt;          &amp;lt;serviceMetadata httpGetEnabled="true" /&amp;gt;&lt;br /&gt;        &amp;lt;/behavior&amp;gt;&lt;br /&gt;      &amp;lt;/serviceBehaviors&amp;gt;&lt;br /&gt;      &lt;br /&gt;      &amp;lt;endpointBehaviors&amp;gt;&lt;br /&gt;        &amp;lt;behavior name="ClockServiceBehavior"&amp;gt;&lt;br /&gt;          &amp;lt;enableWebScript/&amp;gt;&lt;br /&gt;        &amp;lt;/behavior&amp;gt;&lt;br /&gt;      &amp;lt;/endpointBehaviors&amp;gt;&lt;br /&gt;    &amp;lt;/behaviors&amp;gt;&lt;br /&gt;        &lt;br /&gt;    &amp;lt;services&amp;gt;&lt;br /&gt;      &amp;lt;service name="WCF_TEST.ClockService" behaviorConfiguration="MetaDataBehavior"&amp;gt;&lt;br /&gt;        &amp;lt;endpoint address="" &lt;br /&gt;                  behaviorConfiguration="ClockServiceBehavior" &lt;br /&gt;                  binding="webHttpBinding" &lt;br /&gt;                  name="ClockService" &lt;br /&gt;                  contract="WCF_TEST.IClockService"/&amp;gt;&lt;br /&gt;      &amp;lt;/service&amp;gt;&lt;br /&gt;    &amp;lt;/services&amp;gt;&lt;br /&gt;    &lt;br /&gt;  &amp;lt;/system.serviceModel&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;La principale différence avec la configuration standard est au niveau du binding du endpoint. Par défaut le binding est définit en tant que &lt;a href='http://msdn.microsoft.com/fr-fr/library/system.servicemodel.wshttpbinding.aspx'&gt;wsHttpBinding&lt;/a&gt; (messages soap) ; Pour parler Json il nous faut choisir le binding &lt;a href='http://msdn.microsoft.com/fr-fr/library/system.servicemodel.webhttpbinding.aspx'&gt;webHttpBinding&lt;/a&gt; (JSon).&lt;/p&gt; &lt;p&gt;Voila, relancez la page web… tadam… c’est magique.&lt;/p&gt; &lt;p&gt;Dans la prochaine partie de cet article je tacherais de vous montrer comment éviter d’avoir à écrire les blocs de javascript xhrPost en passant par &lt;a href='http://www.dojotoolkit.org/book/dojo-book-0-9/part-3-programmatic-dijit-and-dojo/ajax-transports/remote-procedure-call-rpc'&gt;dojo.rpc&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Christophe, t’as plus qu’a réécrire LCCFamily :)&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1146316188254265608-1045942312129307472?l=mymemoryleaks.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mymemoryleaks.blogspot.com/feeds/1045942312129307472/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1146316188254265608&amp;postID=1045942312129307472' title='1 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1146316188254265608/posts/default/1045942312129307472'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1146316188254265608/posts/default/1045942312129307472'/><link rel='alternate' type='text/html' href='http://mymemoryleaks.blogspot.com/2009/04/dojo-wcf-1ere-partie_7342.html' title='Dojo + WCF [1ere Partie]'/><author><name>Fabrice Michellonet</name><uri>http://www.blogger.com/profile/10201820062243684793</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_yYUu3sWKdtU/SE76j2im4AI/AAAAAAAACFA/OgO15yojzu8/S220/Fabrice_MICHELLONET.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1146316188254265608.post-3567024816819608154</id><published>2009-04-06T22:30:00.006+02:00</published><updated>2009-07-22T22:30:53.071+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Autre'/><title type='text'>Microsoft Web Platform Installer</title><content type='html'>&lt;p&gt;Il y a quelques jours, je suis tombé un peu par hazard sur la page &lt;a href='http://www.microsoft.com/web/downloads/platform.aspx'&gt;Microsoft Web Platform Installer&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;De quoi s'agit-t-il? Sans avoir testé mais d'après les infos qui sont distillées sur ce mini site, cela prend la forme d'un installeur qui vous aidera à mettre en place : &lt;ul&gt; &lt;li&gt;Le framework .NET evidemment&lt;/li&gt; &lt;li&gt;Le serveur web IIS 7&lt;/li&gt; &lt;li&gt;La base relationnelle SQL Serveur&lt;/li&gt; &lt;li&gt;Les outils de dev : Visual Studio et Expression Web&lt;/li&gt; &lt;li&gt;Et tout un tas d'applications web opensource comme &lt;a href='http://www.dotnetnuke.com/'&gt;DNN&lt;/a&gt;, &lt;a href='http://www.dotnetblogengine.net/'&gt;BlogEngine.NET&lt;/a&gt; etc... &lt;/li&gt; &lt;li&gt;Et tenez vous bien vous trouverez même des applications qui fonctionnent sous PHP (&lt;a href='http://acquia.com/'&gt;Acquia Drupal&lt;/a&gt;, &lt;a href='http://wordpress.org/'&gt;WordPress&lt;/a&gt; etc...)&lt;/li&gt; &lt;/ul&gt; &lt;/p&gt; &lt;p&gt;Personnellement tout cela me fait penser aux initiatives qui furent lancées il y a une petite dizaine d'années en arrière avec des installateurs comme &lt;a href='http://www.easyphp.org/'&gt;EasyPhp&lt;/a&gt; et compagnie... encore une fois, l'histoire se répète!! mais pour le coup, il me semble que c'est plutôt une bonne chose. &lt;/p&gt; &lt;p&gt;Une petite question me traverse l'esprit tout d'un coup; on ne parle pas une seule seconde de &lt;a href='http://technet.microsoft.com/fr-fr/windowsserver/sharepoint/default.aspx'&gt;WSS&lt;/a&gt; dans tout ça... pourtant ça risque bien de faire un peu d'ombre... non?&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1146316188254265608-3567024816819608154?l=mymemoryleaks.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mymemoryleaks.blogspot.com/feeds/3567024816819608154/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1146316188254265608&amp;postID=3567024816819608154' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1146316188254265608/posts/default/3567024816819608154'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1146316188254265608/posts/default/3567024816819608154'/><link rel='alternate' type='text/html' href='http://mymemoryleaks.blogspot.com/2009/04/microsoft-web-platform-installer_9787.html' title='Microsoft Web Platform Installer'/><author><name>Fabrice Michellonet</name><uri>http://www.blogger.com/profile/10201820062243684793</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_yYUu3sWKdtU/SE76j2im4AI/AAAAAAAACFA/OgO15yojzu8/S220/Fabrice_MICHELLONET.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1146316188254265608.post-5265416705535308850</id><published>2009-04-02T23:44:00.005+02:00</published><updated>2009-07-22T22:30:53.057+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Dojo'/><title type='text'>Quel Framework Ajax choisir ?</title><content type='html'>&lt;p&gt;Dojo est désormais passé en version 1.3 avec son lot de nouveautés que je vous laisse découvrir &lt;a href='http://www.dojotoolkit.org/2009/03/31/dojo-1-3-now-available'&gt;ici.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Mais ce qui est plus excitant encore (et qui est presque passé inaperçu) c’est la mise à disposition de &lt;a href='http://dante.dojotoolkit.org/taskspeed/'&gt;TaskSpeed&lt;/a&gt;, un outil de benchmark des principaux Framework Ajax actuellement disponible [&lt;a href='http://jquery.com/'&gt;JQuery&lt;/a&gt;, &lt;a href='http://www.dojotoolkit.org/'&gt;Dojo&lt;/a&gt;, &lt;a href='http://www.prototypejs.org/'&gt;Prototype&lt;/a&gt;, &lt;a href='http://mootools.net/'&gt;MooTools&lt;/a&gt;].&lt;/p&gt; &lt;p&gt;Mais comment benchmarker des Framework qui n’offrent pas tous les mêmes fonctionnalités ? (JQuery n’offre pas de composants graphique par exemple). TaskSpeed propose de les noter sur leur plus petit dénominateur commun, c'est-à-dire la manipulation du DOM HTML.&lt;/p&gt; &lt;p&gt;Sur le site, il est possible à tout un chacun de visualiser les résultats d’une bonne quinzaine de métrique par Framework. J’ai moi-même réalisé le test avec mon navigateur préféré &lt;a href='http://www.mozilla-europe.org/fr/firefox/'&gt;Firefox&lt;/a&gt;... (Jérôme, y’a des gens qui ont fait le test avec &lt;a href='http://www.opera.com/'&gt;Opéra&lt;/a&gt;... je te jure y’a pas que toi qui l’utilise :) ).&lt;/p&gt; &lt;p&gt;Et le vainqueur est... Dojo bien sur.&lt;/p&gt; &lt;p&gt; &lt;a href='http://img211.imageshack.us/img211/9906/totalavgaccrossallbrows.png' dojotype='dojox.image.Lightbox' group='Bench' title='Moyenne par rapport au navigateur'&gt;&lt;img src='http://img12.imageshack.us/img12/9906/totalavgaccrossallbrows.png' alt='Moyenne par rapport au navigateur'/&gt;&lt;/a&gt; &lt;a href='http://img12.imageshack.us/img12/5905/resultff.png' dojotype='dojox.image.Lightbox' group='Bench' title='Résultats FF'&gt;&lt;img src='http://img21.imageshack.us/img21/898/resultffthumb.png' alt='Résultats FF'/&gt;&lt;/a&gt; &lt;a href='http://img4.imageshack.us/img4/5880/resultie8.png' dojotype='dojox.image.Lightbox' group='Bench' title='Résultats IE'&gt;&lt;img src='http://img10.imageshack.us/img10/9327/resultie8thumb.png' alt='Résultats IE'/&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Le dernier est JQuery… Au fait, qui peut me rappeler pourquoi Microsoft à choisit ce Framework pour l’intégrer dans son offre Ajax ?&lt;/p&gt; &lt;p&gt;Afin d’assurer la plus grande transparence, il est possible de voir le code exécuté pour chaque test en cliquant simplement sur la cellule au croisement d’un Framework et d’un browser.&lt;/p&gt; &lt;p&gt;PS : Pour ceux qui se demandent comment sont faits les graphs… il s’agit de dojox.gfx.&lt;/p&gt; &lt;p&gt;PS2 : Je vous laisse aussi découvrir par la même occasion quel est le pire navigateur lorsqu’il s’agit de manipuler le DOM.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1146316188254265608-5265416705535308850?l=mymemoryleaks.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mymemoryleaks.blogspot.com/feeds/5265416705535308850/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1146316188254265608&amp;postID=5265416705535308850' title='3 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1146316188254265608/posts/default/5265416705535308850'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1146316188254265608/posts/default/5265416705535308850'/><link rel='alternate' type='text/html' href='http://mymemoryleaks.blogspot.com/2009/04/quel-framework-ajax-choisir_9454.html' title='Quel Framework Ajax choisir ?'/><author><name>Fabrice Michellonet</name><uri>http://www.blogger.com/profile/10201820062243684793</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_yYUu3sWKdtU/SE76j2im4AI/AAAAAAAACFA/OgO15yojzu8/S220/Fabrice_MICHELLONET.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1146316188254265608.post-4644877099907395786</id><published>2009-03-31T11:41:00.011+02:00</published><updated>2009-07-22T22:30:53.034+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='CSS'/><category scheme='http://www.blogger.com/atom/ns#' term='Autre'/><title type='text'>Webkit... ou comment reproduire les erreurs du passé.</title><content type='html'>&lt;p&gt;A croire que l'histoire se répète indéfiniment, et qu’on ne tire pas de leçons du passé.&lt;/p&gt; &lt;p&gt;Pourquoi ce coup de gueule ? Tout simplement parce que je viens de tomber sur une news qui présente les &lt;b&gt;EXTRAORDINAIRES&lt;/b&gt; nouvelles propriétés CSS du moteur Webkit (utilisé principalement par Safari et Google Chrome)…&lt;/p&gt; &lt;p&gt;Attention mesdames et messieurs, jusqu’à maintenant on utilisait les CSS pour styler un élément, maintenant avec Webkit vous pouvez lui donner un comportement.&lt;/p&gt; &lt;p&gt;La preuve en image : une horloge uniquement en CSS.&lt;/p&gt; &lt;p align="center"&gt;&lt;a href='http://img208.imageshack.us/img208/267/cssclock.png' dojotype='dojox.image.Lightbox' group='CSSClock' title='Horloge CSS'&gt;&lt;img src='http://img148.imageshack.us/img148/8409/cssclockthumb.png' alt='Horloge CSS'/&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Et le fabuleux bout de CSS proprietaire qui va bien... &lt;/p&gt;&lt;pre class='brush:css'&gt;   &lt;br /&gt;      /* -webkit-transition: property duration timing-function */&lt;br /&gt;      #clock img[src*='hour'] {&lt;br /&gt;         -webkit-transform: rotate(90deg);&lt;br /&gt;       }&lt;br /&gt;&lt;br /&gt;      #clock img[src*='second'] {&lt;br /&gt;         -webkit-transition: -webkit-transform 60s linear;&lt;br /&gt;       }&lt;br /&gt;&lt;br /&gt;      #clock:target img[src*='second'] {&lt;br /&gt;         -webkit-transform: rotate(360deg);&lt;br /&gt;       }&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;Comportements vous avez dit ? Mais, normalement ce n’est pas le rôle de Javascript de donner un comportement, dit l’architecte Web ?&lt;/p&gt; &lt;p&gt;Et dire que dans le passé, lorsqu’ Internet Explorer 6 était le seul browser potable du marché (non Jérome &lt;a href="http://links.sourceforge.net/"&gt;Links&lt;/a&gt; n’est pas à proprement parlé un browser :)) des milliers de voix s’élevait contre toutes les fonctions propriétaires que Microsoft avait introduites en marge de la norme.&lt;/p&gt; &lt;p&gt;Tient, la c’est marrant, j’en entends beaucoup moins s’insurger….&lt;/p&gt;&lt;pre class="brush:css"&gt;&lt;br /&gt;      #fabrice {&lt;br /&gt;         -webkit-shutup: 5sec;&lt;br /&gt;      }&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;[Source &lt;a href='http://ajaxian.com/archives/creating-a-clock-in-css'&gt;Ajaxian&lt;/a&gt;]&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1146316188254265608-4644877099907395786?l=mymemoryleaks.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mymemoryleaks.blogspot.com/feeds/4644877099907395786/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1146316188254265608&amp;postID=4644877099907395786' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1146316188254265608/posts/default/4644877099907395786'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1146316188254265608/posts/default/4644877099907395786'/><link rel='alternate' type='text/html' href='http://mymemoryleaks.blogspot.com/2009/03/webkit-ou-comment-reproduire-les_5520.html' title='Webkit... ou comment reproduire les erreurs du passé.'/><author><name>Fabrice Michellonet</name><uri>http://www.blogger.com/profile/10201820062243684793</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_yYUu3sWKdtU/SE76j2im4AI/AAAAAAAACFA/OgO15yojzu8/S220/Fabrice_MICHELLONET.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1146316188254265608.post-5365798911778588717</id><published>2009-03-27T23:41:00.005+01:00</published><updated>2009-07-22T22:30:53.005+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Virtual Earth'/><category scheme='http://www.blogger.com/atom/ns#' term='Google Charts'/><title type='text'>Quand Google et Microsoft fonctionnent main dans la main.</title><content type='html'>&lt;p&gt;Dernièrement, j'ai l'impression que dans le giron de &lt;a href='http://www.microsoft.com/fr/fr/default.aspx'&gt;Microsoft&lt;/a&gt; on s'émeut de plus en plus, parfois outre mesures, de ce qui se fait chez &lt;a href='http://www.google.fr'&gt;Google&lt;/a&gt;. Pourtant, je me suis laissé dire qu'il existe surement des terrains ou les deux offres se complètent.&lt;/p&gt; &lt;p&gt;En ce moment par exemple, je travaille chez mon client avec le composant Javascript de &lt;a href='http://maps.live.com/'&gt;Virtual Earth&lt;/a&gt; qui permet, comme tout le monde doit déjà le savoir, d’afficher de belles cartes géographique avec zoom, navigation interactive et toutes les petites choses sexy que les aficionados de &lt;a href='http://maps.google.com/'&gt;Google Maps&lt;/a&gt; apprécient.&lt;/p&gt; &lt;p&gt;Imaginez maintenant que vous ne souhaitiez pas uniquement &lt;ul&gt; &lt;li&gt;explorer les environs de votre lieu d’habitation,&lt;/li&gt; &lt;li&gt;ou bien encore prévoir le trajet en faire en auto pour vous rendre dans votre prochain lieu de villégiature&lt;/li&gt; &lt;/ul&gt; mais que vous souhaitiez pour votre projet &lt;a href='http://en.wikipedia.org/wiki/Business_intelligence'&gt;BI&lt;/a&gt; actuel afficher vos indicateurs quels qu’ils soient sur une jolie carte le tout sur une simple page web… &lt;/p&gt; &lt;p&gt;Bien, je suis sur que vous me voyez venir avec mes gros sabots… &lt;/p&gt; &lt;p&gt;Alors prenons une petite dose de &lt;a href='http://maps.live.com/'&gt;Virtual Earth&lt;/a&gt; et un soupçon de &lt;a href='http://code.google.com/apis/chart/'&gt;Google Charts&lt;/a&gt; et l’on obtient alors quelque chose dans ce goût la : &lt;/p&gt; &lt;a href='http://img257.imageshack.us/img257/8890/repartparis.png' dojotype='dojox.image.Lightbox' group='GoogleAndMS' title='Carte + Graph'&gt;&lt;img src='http://img22.imageshack.us/img22/9805/repartparisthumb.png' alt='Carte + Graph' width='80' height='60'/&gt;&lt;/a&gt; &lt;p&gt;Et pour ceux qui se demande comment on peut faire ce genre de chose voici le code, somme toute très très simple : &lt;/p&gt;&lt;pre class='brush:html'&gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;html xmlns="http://www.w3.org/1999/xhtml" &amp;gt;&lt;br /&gt;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;&lt;br /&gt; Virtual Earth&lt;br /&gt;&amp;lt;/title&amp;gt;&amp;lt;meta http-equiv="Content-Type" content="text/html; charset=utf-8" /&amp;gt;&lt;br /&gt;    &amp;lt;script type="text/javascript" src="http://dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=6.2&amp;amp;mkt=fr-FR"&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;    &lt;br /&gt;    &amp;lt;script type="text/javascript"&amp;gt;&lt;br /&gt;        function initialize() {&lt;br /&gt;            map = new VEMap('myMap');&lt;br /&gt;            var ParisLatLong = new VELatLong(48.8667, 2.3333);&lt;br /&gt;            map.LoadMap(ParisLatLong);&lt;br /&gt;            map.Resize(800, 600);&lt;br /&gt;            map.SetZoomLevel(7);&lt;br /&gt;            map.SetCenter(ParisLatLong);&lt;br /&gt;&lt;br /&gt;            var newShape = new VEShape(VEShapeType.Pushpin, ParisLatLong);&lt;br /&gt;&lt;br /&gt;            newShape.SetTitle("Répartition des moyens de transport à Paris");&lt;br /&gt;            newShape.SetDescription('&amp;lt;img src="http://chart.apis.google.com/chart?chtt=un+beau+spacer&amp;amp;chts=ffffff&amp;amp;chs=200x100&amp;amp;chf=bg,s,ffffff&amp;amp;cht=p3&amp;amp;chd=t:56.00,40.00,4.00&amp;amp;chl=Autos|Motos|Autres" alt="My google chart" /&amp;gt;');&lt;br /&gt;            map.AddShape(newShape);&lt;br /&gt;        }&lt;br /&gt;    &amp;lt;/script&amp;gt;&lt;br /&gt;    &lt;br /&gt;    &amp;lt;style type="text/css"&amp;gt;&lt;br /&gt;        HTML, BODY, FORM {margin:0; padding:0; height:100%; width:100%;}&lt;br /&gt;    &amp;lt;/style&amp;gt;&lt;br /&gt;    &lt;br /&gt;&amp;lt;/head&amp;gt;&lt;br /&gt;&amp;lt;body onload="initialize();"&amp;gt;&lt;br /&gt;    &amp;lt;form name="form1" method="post" action="Default.aspx" id="form1"&amp;gt;&lt;br /&gt;        &amp;lt;div id="myMap" style="position:relative; width:100%; height:100%"/&amp;gt;&lt;br /&gt;    &amp;lt;/form&amp;gt;&lt;br /&gt;&amp;lt;/body&amp;gt;&lt;br /&gt;&amp;lt;/html&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;Evidement je laisse libre cours à votre imagination pour rendre vos cartes BI encore plus interactive et bien entendu attractives pour les utilisateurs.&lt;/p&gt; &lt;p&gt;J’en profite pour vous donner deux liens qui m’ont semblé fort intéressants : &lt;ul&gt; &lt;li&gt;&lt;a href='http://www.clabberhead.com/googlechartgenerator.html'&gt;Google Chart Creator&lt;/a&gt; pour créer vos graphs rapidement&lt;/li&gt; &lt;li&gt;&lt;a href='http://www.microsoft.com/downloads/details.aspx?FamilyID=09905eea-f8d4-4af3-bb35-b479bf342e1e&amp;amp;DisplayLang=en'&gt;Virtual Earth Map Control SDK 6.2 offline documentation&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1146316188254265608-5365798911778588717?l=mymemoryleaks.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mymemoryleaks.blogspot.com/feeds/5365798911778588717/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1146316188254265608&amp;postID=5365798911778588717' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1146316188254265608/posts/default/5365798911778588717'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1146316188254265608/posts/default/5365798911778588717'/><link rel='alternate' type='text/html' href='http://mymemoryleaks.blogspot.com/2009/03/quand-google-et-microsoft-fonctionnent_813.html' title='Quand Google et Microsoft fonctionnent main dans la main.'/><author><name>Fabrice Michellonet</name><uri>http://www.blogger.com/profile/10201820062243684793</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_yYUu3sWKdtU/SE76j2im4AI/AAAAAAAACFA/OgO15yojzu8/S220/Fabrice_MICHELLONET.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1146316188254265608.post-1649264751890511723</id><published>2008-10-14T15:40:00.003+02:00</published><updated>2009-07-22T22:30:52.990+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='GreaseMonkey'/><category scheme='http://www.blogger.com/atom/ns#' term='OGame'/><category scheme='http://www.blogger.com/atom/ns#' term='AllyStats'/><title type='text'>AllyStats v0.4</title><content type='html'>&lt;p&gt; Un post très très rapide afin d'annoncer la sortie de la &lt;a href='http://fabrice.michellonet.googlepages.com/AllyStats.user.js'&gt;version 0.4 d'AllyStats&lt;/a&gt;. Cette version permet de : &lt;ul&gt; &lt;li&gt;utiliser le script dans tout les pays.&lt;/li&gt; &lt;li&gt;utiliser le script si vous possedez plusieurs compte sur des univers différents.&lt;/li&gt; &lt;li&gt;modifier la couleur de fond des graphiques.&lt;/li&gt; &lt;li&gt;meilleure proportion des graphs.&lt;/li&gt; &lt;li&gt;correction du calcul de la progression lors de l'export HTML&lt;/li&gt; &lt;/ul&gt; &lt;/p&gt;&lt;p&gt;Toutes vos remarques ont étés prises en compte et je les intégrerais à mesure dans le script... il me faut juste un peu de temps... libre&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1146316188254265608-1649264751890511723?l=mymemoryleaks.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mymemoryleaks.blogspot.com/feeds/1649264751890511723/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1146316188254265608&amp;postID=1649264751890511723' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1146316188254265608/posts/default/1649264751890511723'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1146316188254265608/posts/default/1649264751890511723'/><link rel='alternate' type='text/html' href='http://mymemoryleaks.blogspot.com/2008/10/allystats-v04_5196.html' title='AllyStats v0.4'/><author><name>Fabrice Michellonet</name><uri>http://www.blogger.com/profile/10201820062243684793</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_yYUu3sWKdtU/SE76j2im4AI/AAAAAAAACFA/OgO15yojzu8/S220/Fabrice_MICHELLONET.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1146316188254265608.post-4195825208691895626</id><published>2008-09-26T11:29:00.003+02:00</published><updated>2009-07-22T22:30:52.973+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='GreaseMonkey'/><category scheme='http://www.blogger.com/atom/ns#' term='Dojo'/><category scheme='http://www.blogger.com/atom/ns#' term='OGame'/><title type='text'>OGame Skript [FR] v0.3</title><content type='html'>&lt;p&gt;Depuis l'annonce de la première version Française d'OGame Skript sur le &lt;a href='http://board.ogame.fr/thread.php?threadid=852121&amp;amp;threadview=0'&gt;forum officiel OGame&lt;/a&gt;, les choses ont pris une bonne tournure. En effet l'accueil qui lui à été réservé à été plutôt bon, plusieurs personnes m'ont gentillement aider à corriger les coquilles qui se sont faufilées par ci par là, certains allant même jusqu'à poster les corrections nécessaires dans telle ou telle regexp.&lt;/p&gt;&lt;p&gt;Je ne pouvais rêver mieux... encore merci à tout ceux qui participent à améliorer le script.&lt;/p&gt;&lt;p&gt;Ainsi grâce au travail de tous, j'ai le plaisir de releaser la version 0.3 de cette traduction Française du script qui comporte toutes les corrections demandées sur le board OGame.Pour les plus préssés, le script est diponible &lt;a href='http://fabrice.michellonet.googlepages.com/ogamelangfr.user.js'&gt;ici&lt;/a&gt; le temps qu'il soit publié sur le site &lt;a href='http://www.ogame-skript.com/'&gt;OGame Skript&lt;/a&gt; officiel; Fallait bien que je vous fasse profiter de la primeur.&lt;/p&gt; &lt;p&gt;Pour cette seconde release, il n'y aura pas de Changelog, car je savais qu'il y aurait beaucoup de remontées, mais promis la prochaine fois, je tracerais exactement tout les changements.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1146316188254265608-4195825208691895626?l=mymemoryleaks.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mymemoryleaks.blogspot.com/feeds/4195825208691895626/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1146316188254265608&amp;postID=4195825208691895626' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1146316188254265608/posts/default/4195825208691895626'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1146316188254265608/posts/default/4195825208691895626'/><link rel='alternate' type='text/html' href='http://mymemoryleaks.blogspot.com/2008/09/ogame-skript-fr-v03_6034.html' title='OGame Skript [FR] v0.3'/><author><name>Fabrice Michellonet</name><uri>http://www.blogger.com/profile/10201820062243684793</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_yYUu3sWKdtU/SE76j2im4AI/AAAAAAAACFA/OgO15yojzu8/S220/Fabrice_MICHELLONET.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1146316188254265608.post-5208941890372498778</id><published>2008-09-22T23:36:00.003+02:00</published><updated>2009-07-22T22:30:52.953+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='SSAS'/><title type='text'>ASCMD : Parametrez vos scripts SSAS.</title><content type='html'>&lt;p&gt;Beaucoup d'entre vous doivent dors et déjà connaitre cette astuce qui facilite les problématiques de déploiement de vos cubes Olap (&lt;a href='http://en.wikipedia.org/wiki/Microsoft_Analysis_Services'&gt;Sql Server Analysis Services&lt;/a&gt;); Pour ma part je n'ai découvert qu'aujourd'hui qu'il est possible de parametrer les scripts &lt;a href='http://en.wikipedia.org/wiki/XMLA'&gt;XMLA&lt;/a&gt;, &lt;a href='http://en.wikipedia.org/wiki/Multidimensional_Expressions'&gt;MDX &lt;/a&gt;et &lt;a href='http://msdn.microsoft.com/fr-fr/library/ms132058%28SQL.90%29.aspx'&gt;DMX&lt;/a&gt; lors de leur execution via ASCMD.&lt;/p&gt; &lt;p&gt;Petit retour en arrière, ASCMD est un utilitaire en ligne de commande qui permet d'exécuter des scripts sur une instance d'Analysis Services locale ou distante. Le code source est fournit dans les &lt;a href='http://www.codeplex.com/MSFTASProdSamples/Release/ProjectReleases.aspx?ReleaseId=4001'&gt;samples de SQL Server&lt;/a&gt; sous forme d'un projet C# à compiler.&lt;/p&gt; &lt;p&gt;Dans le cadre d'une livraison chez un de vos client par exemple, ASCMD s'avère fort utile car il permet de scripter toutes les opérations possible que vous souhaiter effectuer; ceci vous affranchit de la lourde tache des backup/restore couramment usités dans la version 2000 d'Analysis Services.&lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;p&gt;Prenons un exemple concret; Le script suivant, permet de modifier le nom du serveur sur lequel est disponible la source de données relationnelle : &lt;/p&gt;&lt;pre class='brush:xml'&gt;&lt;br /&gt;&amp;lt;Alter ObjectExpansion="ExpandFull" xmlns="http://schemas.microsoft.com/analysisservices/2003/engine"&amp;gt;&lt;br /&gt;    &amp;lt;Object&amp;gt;&lt;br /&gt;        &amp;lt;DatabaseID&amp;gt;Adventure Works DW&amp;lt;/DatabaseID&amp;gt;&lt;br /&gt;        &amp;lt;DataSourceID&amp;gt;Adventure Works DW&amp;lt;/DataSourceID&amp;gt;&lt;br /&gt;    &amp;lt;/Object&amp;gt;&lt;br /&gt;    &amp;lt;ObjectDefinition&amp;gt;&lt;br /&gt;        &amp;lt;DataSource xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ddl2="http://schemas.microsoft.com/analysisservices/2003/engine/2" xmlns:ddl2_2="http://schemas.microsoft.com/analysisservices/2003/engine/2/2" xsi:type="RelationalDataSource"&amp;gt;&lt;br /&gt;            &amp;lt;ID&amp;gt;Adventure Works DW&amp;lt;/ID&amp;gt;&lt;br /&gt;            &amp;lt;Name&amp;gt;Adventure Works DW&amp;lt;/Name&amp;gt;&lt;br /&gt;            &amp;lt;ConnectionString&amp;gt;Provider=SQLNCLI.1;Data Source=$(ServerName);Persist Security Info=False;Integrated Security=SSPI;Initial Catalog=AdventureWorksDW&amp;lt;/ConnectionString&amp;gt;&lt;br /&gt;            &amp;lt;ImpersonationInfo&amp;gt;&lt;br /&gt;                &amp;lt;ImpersonationMode&amp;gt;ImpersonateServiceAccount&amp;lt;/ImpersonationMode&amp;gt;&lt;br /&gt;            &amp;lt;/ImpersonationInfo&amp;gt;&lt;br /&gt;            &amp;lt;Timeout&amp;gt;PT0S&amp;lt;/Timeout&amp;gt;&lt;br /&gt;        &amp;lt;/DataSource&amp;gt;&lt;br /&gt;    &amp;lt;/ObjectDefinition&amp;gt;&lt;br /&gt;&amp;lt;/Alter&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;Notez la déclaration et l'utilisation de la variable &lt;b&gt;$(ServerName)&lt;/b&gt;. Celle-ci va pouvoir être définit lors de l'execution de la manière suivante :&lt;/p&gt;&lt;p&gt;&lt;pre class='brush:bash'&gt;ascmd.exe -S localhost -i modifyDS.xmla -v ServerName=My_production_server&lt;/pre&gt;&lt;/p&gt; &lt;p&gt;Cette fonctionnalité ouvre de nouveaux horizons pour les déploiements, plus besoin de demander à vos interlocuteurs de faire ceci ou cela; &lt;/p&gt; &lt;ul&gt; &lt;li&gt;Scriptez vos actions sous forme de scripts XMLA parametrés.&lt;/li&gt; &lt;li&gt;Livrez un fichier ini, seul point que votre interlocuteur devra éditer afin de le faire correspondre à son environnement.&lt;/li&gt; &lt;li&gt;Demander à votre interlocuteur de lancer le seul fichier fichier bat fournit réunissant l'ensemble des commandes à executer.&lt;/li&gt; &lt;li&gt;Vous êtes zen, vous venez de considérablement diminuer les chances d'erreurs du à une mauvaise manipulation de votre interlocuteur.&lt;/li&gt; &lt;/ul&gt; &lt;p/&gt;&lt;p&gt;Bon déploiements à tous.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1146316188254265608-5208941890372498778?l=mymemoryleaks.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mymemoryleaks.blogspot.com/feeds/5208941890372498778/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1146316188254265608&amp;postID=5208941890372498778' title='2 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1146316188254265608/posts/default/5208941890372498778'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1146316188254265608/posts/default/5208941890372498778'/><link rel='alternate' type='text/html' href='http://mymemoryleaks.blogspot.com/2008/09/ascmd-parametrez-vos-scripts-ssas_3610.html' title='ASCMD : Parametrez vos scripts SSAS.'/><author><name>Fabrice Michellonet</name><uri>http://www.blogger.com/profile/10201820062243684793</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_yYUu3sWKdtU/SE76j2im4AI/AAAAAAAACFA/OgO15yojzu8/S220/Fabrice_MICHELLONET.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1146316188254265608.post-2658263734792063041</id><published>2008-09-21T23:20:00.004+02:00</published><updated>2009-07-22T22:30:52.935+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='GreaseMonkey'/><category scheme='http://www.blogger.com/atom/ns#' term='OGame'/><category scheme='http://www.blogger.com/atom/ns#' term='AllyStats'/><title type='text'>OGame AllyStats</title><content type='html'>&lt;p&gt; Je vous l'avais annoncé à demi mots le 12 septembre dernier (&lt;a href='http://mymemoryleaks.blogspot.com/2008/09/ogame-skript-fr-releas.html'&gt;OGame Skript [Fr] releasé&lt;/a&gt;), j'allais écrire au moins un script &lt;a href='http://www.greasespot.net/'&gt; greasemonkey&lt;/a&gt; pour OGame. Voila c'est chose faite, enfin pour une béta :)... je vous présente AllyStats; L'idée est d'améliorer la page statistique d'alliance (merci ptitony &amp;amp; les Freeglad pour l'idée) de la manièere suivante : &lt;/p&gt; &lt;a href='http://lh3.ggpht.com/fabrice.michellonet/SNayNn-u8SI/AAAAAAAAC-8/AwFuoS1zhPw/Normal.jpg' dojotype='dojox.image.Lightbox' group='ogame' title='Sans le script'&gt; &lt;img src='http://lh3.ggpht.com/fabrice.michellonet/SNayNn-u8SI/AAAAAAAAC-8/AwFuoS1zhPw/s144/Normal.jpg' alt='image 1 sur 4' width='100' height='40'/&gt;&lt;/a&gt; &lt;a href='http://lh5.ggpht.com/fabrice.michellonet/SNakp_ofGKI/AAAAAAAAC-A/j0xuPKtlurU/Overview.jpg' dojotype='dojox.image.Lightbox' group='ogame' title='AllyStats - Visualiser la progression des joueurs'&gt; &lt;img src='http://lh5.ggpht.com/fabrice.michellonet/SNakp_ofGKI/AAAAAAAAC-A/j0xuPKtlurU/s144/Overview.jpg' alt='image 2 sur 4' width='100' height='40'/&gt;&lt;/a&gt; &lt;a href='http://lh5.ggpht.com/fabrice.michellonet/SNakqciZBLI/AAAAAAAAC-I/IMtJpvz_sUk/Load.jpg' dojotype='dojox.image.Lightbox' group='ogame' title='AllyStats - Chargez un classement précédent'&gt; &lt;img src='http://lh5.ggpht.com/fabrice.michellonet/SNakqciZBLI/AAAAAAAAC-I/IMtJpvz_sUk/s144/Load.jpg' alt='image 3 sur 4' width='100' height='40'/&gt;&lt;/a&gt; &lt;a href='http://lh5.ggpht.com/fabrice.michellonet/SNakqm_g5gI/AAAAAAAAC-Q/eRIVqfFFZ9U/Export.jpg' dojotype='dojox.image.Lightbox' group='ogame' title='AllyStats - Exporter pour votre forum'&gt; &lt;img src='http://lh5.ggpht.com/fabrice.michellonet/SNakqm_g5gI/AAAAAAAAC-Q/eRIVqfFFZ9U/s144/Export.jpg' alt='image 4 sur 4' width='100' height='40'/&gt;&lt;/a&gt; &lt;p&gt;Si ce que vous avez vu vous plais, n'hésitez pas à l'installer.&lt;/p&gt; &lt;p&gt;&lt;b&gt;&lt;u&gt;Pré-requis&lt;/u&gt;&lt;/b&gt;&lt;/p&gt; &lt;p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href='http://www.mozilla-europe.org/fr/firefox/'&gt;Firefox 3.0&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href='https://addons.mozilla.org/fr/firefox/addon/748'&gt;greasemonkey&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/p&gt; &lt;p&gt;Il est possible qu'il vous soit demandé de redémarrer Firefox; Dans ce cas, &lt;b&gt;surtout&lt;/b&gt; faites le.&lt;/p&gt; &lt;p&gt;&lt;b&gt;&lt;u&gt;Installation&lt;/u&gt;&lt;/b&gt;&lt;/p&gt; &lt;p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href='http://fabrice.michellonet.googlepages.com/AllyStats.user.js'&gt;Installer le script AllyStats&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/p&gt; &lt;p&gt;&lt;b&gt;&lt;u&gt;Synchronisation&lt;/u&gt;&lt;/b&gt;&lt;/p&gt; &lt;p&gt;Pour les utilisateurs avancés, il vous est possible de (re)charger les statistiques d'une période précédente en suivant le formalisme &lt;a href='http://fr.wikipedia.org/wiki/JSON'&gt;JSON&lt;/a&gt; suivant : &lt;/p&gt; &lt;p&gt;&lt;pre class='brush:js'&gt;&lt;br /&gt;[&lt;br /&gt; {"Name":"Player 1","Points":"1000","Homeworld":"[x:xxx:xx]"},&lt;br /&gt; {"Name":"Player 2","Points":"1242","Homeworld":"[x:xxx:xx]"},&lt;br /&gt; ... &lt;br /&gt; {"Name":"Player N","Points":"758","Homeworld":"[x:xxx:xx]"}&lt;br /&gt;]&lt;br /&gt;&lt;/pre&gt;&lt;/p&gt; &lt;p&gt;Cette feature vous permettra également de synchroniser les stats de tout les membres de votre alliance lors de la première installation.&lt;/p&gt; &lt;p&gt; &lt;b&gt;&lt;u&gt;Utilisation&lt;/u&gt;&lt;/b&gt;&lt;/p&gt; &lt;p&gt; Elle est des plus simple; dès la première utilisation AllyStats va stocker les points de chaque joueur de votre alliance. A mesure que leur points augmentent, le graphique qui est apparu dans la nouvelle colonne mettra en évidence leur progression. Si vous souhaitez surveiller l'évolution de vos coéquipier de manière hebdomadaire, il vous faudra réinitialiser le classement en utilisant le bouton prévu à cet effet (le second). Finalement, si vous disposez également d'un forum ou vous vous retrouvez avec vos amis, AllytStats vous donne la possibilité d'exporter vos progressions au format &lt;a href='http://fr.wikipedia.org/wiki/Hypertext_Markup_Language'&gt;html&lt;/a&gt; &amp;amp; &lt;a href='http://fr.wikipedia.org/wiki/Bbcode'&gt;bbcode&lt;/a&gt;&lt;/p&gt; &lt;p&gt; N'hésitez pas à me dire ce que vous en pensez, ainsi que me faire part de toutes vos remarques constructives.&lt;/p&gt; &lt;p&gt; Enjoy&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1146316188254265608-2658263734792063041?l=mymemoryleaks.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mymemoryleaks.blogspot.com/feeds/2658263734792063041/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1146316188254265608&amp;postID=2658263734792063041' title='1 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1146316188254265608/posts/default/2658263734792063041'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1146316188254265608/posts/default/2658263734792063041'/><link rel='alternate' type='text/html' href='http://mymemoryleaks.blogspot.com/2008/09/ogame-allystats_5434.html' title='OGame AllyStats'/><author><name>Fabrice Michellonet</name><uri>http://www.blogger.com/profile/10201820062243684793</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_yYUu3sWKdtU/SE76j2im4AI/AAAAAAAACFA/OgO15yojzu8/S220/Fabrice_MICHELLONET.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh3.ggpht.com/fabrice.michellonet/SNayNn-u8SI/AAAAAAAAC-8/AwFuoS1zhPw/s72-c/Normal.jpg' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1146316188254265608.post-7664560874389120602</id><published>2008-09-17T23:51:00.004+02:00</published><updated>2009-07-22T22:30:52.920+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Dojo'/><title type='text'>Dojo Lightbox</title><content type='html'>&lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;&lt;p&gt;Aujourd'hui je me propose d'illustrer la mise en place de &lt;a href='http://www.lokeshdhakar.com/projects/lightbox2/'&gt;lightbox&lt;/a&gt; à la sauce &lt;a href='http://www.dojotoolkit.org/'&gt;Dojo&lt;/a&gt; comme toujours. Pour ceux qui n'en ont jamais entendu parler, dépêchez-vous cliquez sur les images ci-dessous.&lt;/p&gt; &lt;a title='Cliquez sur le bouton &amp;gt; pour passer à la suite.' group='plants' dojotype='dojox.image.Lightbox' href='http://www.lokeshdhakar.com/projects/lightbox2/images/image-3.jpg'&gt;&lt;img height='40' width='100' alt='image 1 sur 3' src='http://www.lokeshdhakar.com/projects/lightbox2/images/thumb-3.jpg'/&gt;&lt;/a&gt; &lt;a title='Sinon utilisez la flèche droite de votre clavier.' group='plants' dojotype='dojox.image.Lightbox' href='http://www.lokeshdhakar.com/projects/lightbox2/images/image-4.jpg'&gt;&lt;img height='40' width='100' alt='image 2 sur 3 ' src='http://www.lokeshdhakar.com/projects/lightbox2/images/thumb-4.jpg'/&gt;&lt;/a&gt; &lt;a title='Utilisez la touche Echap pour quitter.' group='plants' dojotype='dojox.image.Lightbox' href='http://www.lokeshdhakar.com/projects/lightbox2/images/image-6.jpg'&gt;&lt;img height='40' width='100' alt='image 3 sur 3' src='http://www.lokeshdhakar.com/projects/lightbox2/images/thumb-6.jpg'/&gt;&lt;/a&gt; &lt;p&gt;L'implémentation est fortement inspirée de la librairie de Lokesh Dhakar; d'ailleurs l'équipe &lt;a href='http://www.dojotoolkit.org/'&gt;Dojo&lt;/a&gt; n'hésite pas à le dire ouvertement &lt;a href='http://dojotoolkit.org/book/dojo-book-0-9/part-5-dojox/dojox-image/lightbox'&gt;ici&lt;/a&gt;. Mais alors quel intérêt à utiliser l'implémentation faite par &lt;a href='http://www.dojotoolkit.org/'&gt;Dojo&lt;/a&gt; plutôt que la version originale? Pour être franc, la seule raison qui puisse vous faire choisir celle de &lt;a href='http://www.dojotoolkit.org/'&gt;Dojo&lt;/a&gt; est le fait d'utiliser déjà ce framework, car honnêtement la version originale est esthétiquement un tout petit peu mieux.&lt;/p&gt;&lt;p&gt;J'entends déjà certain d'entre vous dire, mais pourquoi ne pas utiliser &lt;a href='http://www.lokeshdhakar.com/projects/lightbox2/'&gt;lightbox&lt;/a&gt; et &lt;a href='http://www.dojotoolkit.org/'&gt;Dojo&lt;/a&gt; conjointement. C'est effectivement possible, mais sachez que &lt;a href='http://www.lokeshdhakar.com/projects/lightbox2/'&gt;lightbox&lt;/a&gt; se repose sur le framework &lt;a href='http://script.aculo.us/'&gt;scriptaculous&lt;/a&gt; lui-même reposant sur &lt;a href='http://www.prototypejs.org/'&gt;prototype&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Voila... vous commencez à comprendre, vouloir les faire cohabiter signifie aussi ajouter les 2, 3 plus gros framework javascript dans vos pages; bonjour les performances!&lt;/p&gt;&lt;p&gt;Le choix se fait donc assez rapidement, si vous utilisez déjà &lt;a href='http://www.dojotoolkit.org/'&gt;Dojo&lt;/a&gt; alors utilisez leur implémentation; si par contre votre coeur balance plutôt pour &lt;a href='http://script.aculo.us/'&gt;scriptaculous&lt;/a&gt; ou &lt;a href='http://www.prototypejs.org/'&gt;prototype&lt;/a&gt; alors vous préférerez l'implémentation de Lokesh Dhakar.&lt;/p&gt;&lt;p&gt;Bon passons aux choses sérieuses, voici ce qu'il vous faut faire pour utiliser cette jolie feature.&lt;/p&gt; &lt;p&gt;Import des css tundra et image&lt;/p&gt;&lt;pre class='brush:html'&gt;&lt;br /&gt;    &lt;style type='text/css'&gt;&lt;br /&gt;        @import "http://o.aolcdn.com/dojo/1.1.1/dijit/themes/tundra/tundra.css"&lt;br /&gt;        @import "http://o.aolcdn.com/dojo/1.1.1/dojox/image/resources/image.css"&lt;br /&gt;    &lt;/style&gt;&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;&lt;b&gt;Notez l'url pointant vers la seconde css (&lt;i&gt;image.css&lt;/i&gt;). La documentation officielle référence &lt;i&gt;Lightbox.css&lt;/i&gt;, mais c'est malheureusement une erreur.&lt;/b&gt;&lt;/p&gt; &lt;p&gt;Import de la fonctionnalité dans un bloc javascript&lt;/p&gt;&lt;pre class='brush:js' name='code'&gt;&lt;br /&gt; dojo.require("dojox.image.Lightbox");&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;Il ne vous reste plus qu'a l'utiliser maintenant de la manière suivante :&lt;/p&gt;&lt;pre class='brush:html' name='code'&gt;&lt;br /&gt;   &lt;a title='Ma description' group='monGroupe' dojotype='dojox.image.Lightbox' href='img1.jpg'&gt;&lt;br /&gt;      &lt;img height='40' width='100' alt='image 1 sur n' src='thumb-1.jpg'/&gt;&lt;br /&gt;   &lt;/a&gt;&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;&lt;b&gt;Notez l'utilisation de l'attribut group, qui vous permet d'enchainer les images d'une même série.&lt;/b&gt;&lt;/p&gt; &lt;p&gt;J'espère que cette présentation vous donnera des idées pour vos galerie d'images.&lt;/p&gt; &lt;p&gt;&lt;u&gt;&lt;i&gt;Les images utilisées dans l'exemple ci-dessus proviennent du site de &lt;a href='http://www.lokeshdhakar.com/projects/lightbox2/'&gt;Lokesh Dhakar&lt;/a&gt;, que je remercie bien évidemment.&lt;/i&gt;&lt;/u&gt;&lt;/p&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1146316188254265608-7664560874389120602?l=mymemoryleaks.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mymemoryleaks.blogspot.com/feeds/7664560874389120602/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1146316188254265608&amp;postID=7664560874389120602' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1146316188254265608/posts/default/7664560874389120602'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1146316188254265608/posts/default/7664560874389120602'/><link rel='alternate' type='text/html' href='http://mymemoryleaks.blogspot.com/2008/09/dojo-lightbox_17.html' title='Dojo Lightbox'/><author><name>Fabrice Michellonet</name><uri>http://www.blogger.com/profile/10201820062243684793</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_yYUu3sWKdtU/SE76j2im4AI/AAAAAAAACFA/OgO15yojzu8/S220/Fabrice_MICHELLONET.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1146316188254265608.post-5407002099168256533</id><published>2008-09-12T22:30:00.005+02:00</published><updated>2009-07-22T22:30:53.203+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='GreaseMonkey'/><category scheme='http://www.blogger.com/atom/ns#' term='OGame'/><title type='text'>OGame Skript [Fr] releasé</title><content type='html'>&lt;p&gt;Ça y est c'est officiel &lt;a href='http://www.ogame-skript.com/org/'&gt;OGame Skript&lt;/a&gt; est releasé en Français; j'ai d'ailleurs été intégré dans l'équipe.L'accueil qui lui est fait sur le forum officiel d'&lt;a href='http://board.ogame.fr/thread.php?threadid=852121'&gt;OGame&lt;/a&gt; y est plutôt bon.&lt;/p&gt;&lt;p&gt;Il s'agit la de ma première participation à un projet Open Source que je n'ai pas initié... et cela semble être une bonne expérience.&lt;/p&gt;&lt;p&gt;J'ai dans l'idée de proposer des Addons non officiels, alors repassez ici pour avoir des nouvelles.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1146316188254265608-5407002099168256533?l=mymemoryleaks.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mymemoryleaks.blogspot.com/feeds/5407002099168256533/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1146316188254265608&amp;postID=5407002099168256533' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1146316188254265608/posts/default/5407002099168256533'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1146316188254265608/posts/default/5407002099168256533'/><link rel='alternate' type='text/html' href='http://mymemoryleaks.blogspot.com/2008/09/ogame-skript-fr-release_12.html' title='OGame Skript [Fr] releasé'/><author><name>Fabrice Michellonet</name><uri>http://www.blogger.com/profile/10201820062243684793</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_yYUu3sWKdtU/SE76j2im4AI/AAAAAAAACFA/OgO15yojzu8/S220/Fabrice_MICHELLONET.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1146316188254265608.post-2095652001988140500</id><published>2008-09-08T16:20:00.009+02:00</published><updated>2009-07-22T22:30:53.188+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='GreaseMonkey'/><category scheme='http://www.blogger.com/atom/ns#' term='OGame'/><title type='text'>Internationalisation OGame Skript</title><content type='html'>&lt;p&gt;Ceux qui me connaissent savent que j'ai été piqué par le virus &lt;a href="http://www.ogame.fr/"&gt;OGame&lt;/a&gt; depuis bientôt 2 ans. Depuis lors de nombreux groupes de scripteurs (&lt;a href="https://addons.mozilla.org/fr/firefox/addon/748"&gt;Greasemonkey&lt;/a&gt; principalement) se sont formés pour essayer d'enrichir le jeu.&lt;/p&gt;&lt;p&gt;Certain de ces scripts ont étés abandonnées aussi vite qu'ils sont nés... d'autres sont toujours là; C'est le cas d'&lt;a href="http://www.ogame-skript.com/"&gt;Ogame Skript&lt;/a&gt; qui vous l'aurez compris à ma préférence. Seul problème, à l'heure actuelle il n'existe qu'une version Allemande et une autre en Anglais. Pour ma part j'avais hacké le script dans mon coin histoire de pouvoir l'utiliser sur nos univers Français.&lt;/p&gt;&lt;p&gt;Depuis peu l'équipe &lt;a href="http://www.ogame-skript.com/"&gt;Ogame Skript&lt;/a&gt; à mis en place un système de traduction de son script; alors il me semble qu'il est temps pour moi de contribuer à joli projet. Vous trouverez donc &lt;a href="http://fabrice.michellonet.googlepages.com/ogamelangfr.user.js"&gt;ici&lt;/a&gt; l'internationalisation fr pour OGame Skript. J'ai bien entendu proposé mes services directement à l'équipe en charge du projet... mais pour l'instant je n'ai pas eu de réponse.&lt;/p&gt;&lt;p&gt;La version actuelle n'est pas complètement traduite... mais bon elle vous donne déjà accès à la plupart des fonctionnalités.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1146316188254265608-2095652001988140500?l=mymemoryleaks.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mymemoryleaks.blogspot.com/feeds/2095652001988140500/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1146316188254265608&amp;postID=2095652001988140500' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1146316188254265608/posts/default/2095652001988140500'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1146316188254265608/posts/default/2095652001988140500'/><link rel='alternate' type='text/html' href='http://mymemoryleaks.blogspot.com/2008/09/internationalisation-ogame-skript_1035.html' title='Internationalisation OGame Skript'/><author><name>Fabrice Michellonet</name><uri>http://www.blogger.com/profile/10201820062243684793</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_yYUu3sWKdtU/SE76j2im4AI/AAAAAAAACFA/OgO15yojzu8/S220/Fabrice_MICHELLONET.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1146316188254265608.post-385111086699950869</id><published>2008-06-26T14:52:00.003+02:00</published><updated>2009-07-22T22:30:53.176+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='SSAS'/><title type='text'>[François Jehl] : Ouvrir SSAS 2005 sur l'extérieur en utilisant HTTP</title><content type='html'>&lt;p&gt;François à publié un très bon billet (&lt;a href="http://fjehl.blogspot.com/2008/06/ouvrir-ssas-2005-sur-lextrieur-en.html#links"&gt;Ouvrir SSAS 2005 sur l&amp;#39;extérieur en utilisant HTTP&lt;/a&gt;) sur la façon d'implémenter une connectivité HTTP pour Analysis Services 2005.&lt;/p&gt;&lt;p&gt;Comme je lui faisais remarquer dans les commentaires, il est possible d'utiliser l'authentification intégrée de IIS afin que les crédentials du user soient automatiquement passés au serveur AS, ce qui permet de pouvoir facilement utiliser les rôles Olap. Cependant, il faut noter que sous Windows 2003 pour une raison qui m'est inconnue la délégation de compte pour les Administrateurs locaux de la machine ne fonctionne pas avec msmdpump.dll.&lt;/p&gt;&lt;p&gt;De plus, il est également possible d'effectuer la même manip sous Analysis Services 2000; Dans ce cas la Data Pump à placer dans le répertoire virtuel se nomme &lt;code&gt;msxisapi.dll&lt;/code&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1146316188254265608-385111086699950869?l=mymemoryleaks.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mymemoryleaks.blogspot.com/feeds/385111086699950869/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1146316188254265608&amp;postID=385111086699950869' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1146316188254265608/posts/default/385111086699950869'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1146316188254265608/posts/default/385111086699950869'/><link rel='alternate' type='text/html' href='http://mymemoryleaks.blogspot.com/2008/06/francois-jehl-ouvrir-ssas-2005-sur-l-en_26.html' title='[François Jehl] : Ouvrir SSAS 2005 sur l&amp;#39;extérieur en utilisant HTTP'/><author><name>Fabrice Michellonet</name><uri>http://www.blogger.com/profile/10201820062243684793</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_yYUu3sWKdtU/SE76j2im4AI/AAAAAAAACFA/OgO15yojzu8/S220/Fabrice_MICHELLONET.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1146316188254265608.post-8513635829075813880</id><published>2008-06-24T11:18:00.002+02:00</published><updated>2009-07-22T22:30:52.897+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Blogger'/><title type='text'>Masquer la barre Blogger</title><content type='html'>&lt;p&gt;J'ai vu pas mal de billets proposant des solutions permettant de retirer la barre Blogger qui est ajoutée automatiquement en en-tête des blogs. Certaines solutions sont basée sur des CSS, mais malheureusement celles que j'ai essayées ne fonctionnent pas, car la barre est en fait chargée dans un &lt;code&gt;iframe&lt;/code&gt;&lt;/p&gt;&lt;p&gt;Reste alors la solution du javascript.&lt;/p&gt;&lt;p&gt;Voici donc une façon implémenter ça : Tout d'abord recherchez la balise &lt;code&gt;body&lt;/code&gt; dans votre template html et ajoutez l'attribut &lt;code&gt;onload&lt;/code&gt; comme suit.&lt;pre class="brush:html"&gt;&lt;br /&gt;&amp;lt;body onload='removeBloggerBar'&amp;gt;&lt;/pre&gt;&lt;/p&gt;&lt;p&gt;puis dans un bloc &lt;code&gt;script&lt;/code&gt; ajouter la fonction suivante : &lt;pre class="brush:js"&gt;&lt;br /&gt;function removeBloggerBar() {&lt;br /&gt;    var bloggerBar = document.getElementById(&amp;quot;navbar-iframe&amp;quot;);&lt;br /&gt;    bloggerBar.style.display = &amp;quot;none&amp;quot;;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/p&gt;&lt;p&gt;Enregistrez le tout et... voila, la barre n'est plus visible sur votre blog.&lt;p&gt;Comme d'habitude j'en profite pour faire un peu de pub à &lt;a href="http://dojotoolkit.org/"&gt;Dojo&lt;/a&gt;; Ci-dessous la même solution basée sur ce framework, vous verrez qu'il n'y à que très peu de choses qui changent.&lt;/p&gt;&lt;p&gt;Tout d'abord dans la section &lt;code&gt;head&lt;/code&gt; : &lt;pre class="brush:html"&gt;&lt;br /&gt;&amp;lt;script language='javascript' type='text/javascript'&amp;gt;&lt;br /&gt;  dojo.require(&amp;quot;dojo.parser&amp;quot;);&lt;br /&gt;  // ... &lt;br /&gt;  dojo.addOnLoad(removeBloggerBar);&lt;br /&gt;&amp;lt;/script&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;/p&gt;&lt;p&gt;Puis il faut rajouter le code suivant soit dans un bloc &lt;code&gt;script&lt;/code&gt; soit dans un fichier externe lié à votre page.&lt;pre class="brush:js"&gt;&lt;br /&gt;function removeBloggerBar() {&lt;br /&gt;    var bloggerBar = dojo.byId(&amp;quot;navbar-iframe&amp;quot;);&lt;br /&gt;    bloggerBar.style.display = &amp;quot;none&amp;quot;;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/p&gt;&lt;p&gt;Le résultat est identique, la barre Blogger disparait.&lt;/p&gt;&lt;p&gt;Enjoy&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1146316188254265608-8513635829075813880?l=mymemoryleaks.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mymemoryleaks.blogspot.com/feeds/8513635829075813880/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1146316188254265608&amp;postID=8513635829075813880' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1146316188254265608/posts/default/8513635829075813880'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1146316188254265608/posts/default/8513635829075813880'/><link rel='alternate' type='text/html' href='http://mymemoryleaks.blogspot.com/2008/06/masquer-la-barre-blogger_1003.html' title='Masquer la barre Blogger'/><author><name>Fabrice Michellonet</name><uri>http://www.blogger.com/profile/10201820062243684793</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_yYUu3sWKdtU/SE76j2im4AI/AAAAAAAACFA/OgO15yojzu8/S220/Fabrice_MICHELLONET.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1146316188254265608.post-2668923978237786352</id><published>2008-06-20T10:23:00.010+02:00</published><updated>2009-07-22T22:30:52.878+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='CSS'/><title type='text'>Overflow : l'attribut oublié.</title><content type='html'>&lt;p&gt;Hier, Jérome Berthaud, me parlait d'une découverte qu'il avait faite lors de son escapade nocturne de la veille sur la toile. Il cherchait une solution au sempiternel problème soulevé par les éléments &lt;code&gt;floatés&lt;/code&gt; à l'intérieur d'un autre élément de type &lt;code&gt;bloc&lt;/code&gt; et surtout comment revenir dans le flux normal du positionnement. Voici un exemple de ce cas de figure : &lt;pre class="brush:html"&gt;&amp;lt;div id=&amp;quot;outer&amp;quot;&amp;gt;&lt;br /&gt; &amp;lt;div id=&amp;quot;inner&amp;quot;&amp;gt; &amp;lt;h2&amp;gt;A Column&amp;lt;/h2&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;  &amp;lt;h1&amp;gt;Main Content&amp;lt;/h1&amp;gt;&lt;br /&gt;  &amp;lt;p&amp;gt;Lorem ipsum&amp;lt;/p&amp;gt;&lt;br /&gt;&amp;lt;/div&amp;gt;&lt;/pre&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;L'idée ici, est d'avoir une colonne (d'identifiant inner) ne prenant qu'une petite partie de l'espace d'affichage, par exemple une barre de navigation. Et bien sur le reste de l'écran réservé au contenu principal du site. Il nous est bien évidemment possible de définir la taille de cette colonne, mais de par sa nature d'élément de &lt;code&gt;block&lt;/code&gt;, le contenu principal va de facto se retrouver repoussé en dessous d'elle, à moins de choisir de la floater.&lt;/p&gt;&lt;p&gt; Et voilà nous y sommes, si le contenu de la colonne se met a s'allonger et finalement dépasser la longueur du contenu principal, toute la mise en forme s'écroule comme un château de cartes. Alors comment s'assurer que le bloc principal s'ajustera toujours à la longueur de notre colonne?&lt;/p&gt;&lt;p&gt;Ayant moi même rencontré des dizaines de fois ce problème, je m'empresse de lui répondre qu'il faut rajouter à la fin du bloc (d'identifiant outer) un nouvel élément auquel on ajoutera la propriété css &lt;code&gt;clear : both&lt;/code&gt;, mais que malheureusement cette solution salie le code html.&lt;/p&gt; &lt;p&gt;Effectivement, Jérôme convient qu'il s'agit d'une solution (d'ailleurs recommandée par le W3C), mais qu'une bien meilleure solution avait été apportée par &lt;a href='http://pmob.co.uk/'&gt;Paul O’Brien&lt;/a&gt;. Celle-ci consiste à ajouter la propriété css &lt;code&gt;overflow:auto&lt;/code&gt; sur le le bloc principal, et magie le bloc principal s'adapte a la hauteur de la colonne intérieur. &lt;pre class="brush:css"&gt;&lt;br /&gt;#inner &lt;br /&gt;{&lt;br /&gt;  width:26%;&lt;br /&gt;  float:left;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;#outer &lt;br /&gt;{&lt;br /&gt;  background-color:#fff;&lt;br /&gt;  width:100%; &lt;br /&gt;  overflow:auto;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/p&gt;&lt;p&gt;Cerise sur le gâteau, cela fonctionne sur tout les navigateurs excepté Netscpate 4...&lt;/p&gt;&lt;p&gt;C'est surement une des meilleure astuce css de ces derniers mois, merci &lt;a href='http://pmob.co.uk/'&gt;Paul O’Brien&lt;/a&gt; pour l'avoir découverte et merci Jérôme de me l'avoir montrée.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1146316188254265608-2668923978237786352?l=mymemoryleaks.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mymemoryleaks.blogspot.com/feeds/2668923978237786352/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1146316188254265608&amp;postID=2668923978237786352' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1146316188254265608/posts/default/2668923978237786352'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1146316188254265608/posts/default/2668923978237786352'/><link rel='alternate' type='text/html' href='http://mymemoryleaks.blogspot.com/2008/06/overflow-l-oublie_20.html' title='Overflow : l&amp;#39;attribut oublié.'/><author><name>Fabrice Michellonet</name><uri>http://www.blogger.com/profile/10201820062243684793</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_yYUu3sWKdtU/SE76j2im4AI/AAAAAAAACFA/OgO15yojzu8/S220/Fabrice_MICHELLONET.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1146316188254265608.post-5293718482893778235</id><published>2008-06-11T13:54:00.005+02:00</published><updated>2009-07-22T22:30:52.864+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Dojo'/><title type='text'>Retour sur le Border Container</title><content type='html'>&lt;p&gt;Je me suis peut-être un peu emballé sur le &lt;a href="http://dojotoolkit.org/book/dojo-book-0-9/part-2-dijit/layout/border-container"&gt;Border Container&lt;/a&gt;; je le pensais un peu plus flexible, mais finalement c'est moi qui ai sur-évaluer ses possibilités. Ce composant propose de séparer la zone d'affichage au maximum 4 parties distinctes : &lt;ul&gt;&lt;li&gt;une entête&lt;/li&gt; &lt;li&gt;une partie de gauche&lt;/li&gt; &lt;li&gt;une partie de centrale (obligatoire)&lt;/li&gt; &lt;li&gt;une partie de droite&lt;/li&gt; &lt;li&gt;un pied de page&lt;/li&gt; &lt;/ul&gt;&lt;img src="http://fabrice.michellonet.googlepages.com/border_container_0.png" alt="border container"/&gt;&lt;/p&gt;&lt;p&gt;Partant de ce principe je divise donc ma zone d'affichage en 4, commence à styler le tout puis à mesure que je rajoute des billets la zone centrale grandit et je suis bientôt obligé d'ajouter un overflow dessus afin de pouvoir lire l'intégralité des posts. Arrgg, ce n'est pas ce que je souhaitais; j'aurais préféré que le scroll se fasse sur l'ensemble de la page et non pas uniquement sur la zone centrale ou une barre de scroll est du plus mauvais effet.&lt;/p&gt;&lt;p&gt;Alors bien évidement cela n'est pas incontournable, en sortant le &lt;a href="http://dojotoolkit.org/book/dojo-book-0-9/part-2-dijit/layout/content-pane"&gt;ContentPane&lt;/a&gt; central en dehors du &lt;a href="http://dojotoolkit.org/book/dojo-book-0-9/part-2-dijit/layout/border-container"&gt;Border Container&lt;/a&gt; et de le positionner uniquement en CSS. Mais selon moi ce n'est pas une solution saine, car on se retrouve à devoir rajouter des &lt;code&gt;div&lt;/code&gt; faisant office de &lt;code&gt;clear&lt;/code&gt; ou de &lt;code&gt;wrapper&lt;/code&gt; afin de faire tenir tout ce joli petit monde en place, avec une unique scrollbar sur le viewport.&lt;/p&gt;&lt;p&gt;En conclusion, le &lt;a href="http://dojotoolkit.org/book/dojo-book-0-9/part-2-dijit/layout/border-container"&gt;Border Container&lt;/a&gt; est vraiment génial lorsque l'on doit mettre en place un layout qui doit tenir totalement sur les dimensions du viewport sans scroll de page. Ainsi, pour ce blog j'ai finalement retiré ce widget et suis repassé sur un layout 100% CSS, car tant qu'a devoir "salir" le code html avec des balises de mise en page, je n'allais pas garder en plus des traitements javascript demandé par le composant&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1146316188254265608-5293718482893778235?l=mymemoryleaks.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mymemoryleaks.blogspot.com/feeds/5293718482893778235/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1146316188254265608&amp;postID=5293718482893778235' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1146316188254265608/posts/default/5293718482893778235'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1146316188254265608/posts/default/5293718482893778235'/><link rel='alternate' type='text/html' href='http://mymemoryleaks.blogspot.com/2008/06/retour-sur-le-border-container_8087.html' title='Retour sur le Border Container'/><author><name>Fabrice Michellonet</name><uri>http://www.blogger.com/profile/10201820062243684793</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_yYUu3sWKdtU/SE76j2im4AI/AAAAAAAACFA/OgO15yojzu8/S220/Fabrice_MICHELLONET.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1146316188254265608.post-2296189470619673282</id><published>2008-06-06T15:24:00.012+02:00</published><updated>2009-07-22T22:30:52.847+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Dojo'/><title type='text'>Dojo et Blogger, ça roule.</title><content type='html'>&lt;p&gt; Comme vous pouvez le voir le templating du blog avance; Je me suis basé sur le template &lt;a href='http://5thirtyone.com/wordpress-foliage-theme'&gt;foliage&lt;/a&gt;, enfin surtout sur les artworks. Pour l'instant vous pouvez découvrir le layout global ainsi qu'une première version de la présentation des billets. A ce propos, je posterais bientôt un tutoriel "step by step" sur la mise en forme d'un widget, surement le widget Blog qui m'a valu de me faire quelques cheveux blancs. &lt;/p&gt;&lt;p&gt;Comme évoqué dans mon premier post &lt;a href='http://mymemoryleaks.blogspot.com/2008/06/demarrage.html'&gt;Démarrage&lt;/a&gt; je me base sur le framework &lt;a href='http://dojotoolkit.org/'&gt;Dojo&lt;/a&gt; pour customiser ce blog. Ainsi la mise en forme 2 colonnes Header + Footer est réalisé avec le composant &lt;a href='http://dojotoolkit.org/book/dojo-book-0-9/part-2-dijit/layout/border-container'&gt;Border Container&lt;/a&gt; qui fonctionne de manière semblable à celle du &lt;a href='http://java.sun.com/j2se/1.4.2/docs/api/java/awt/BorderLayout.html'&gt;BorderLayout&lt;/a&gt; de Java.&lt;/p&gt;&lt;p&gt;Pour utiliser &lt;a href='http://dojotoolkit.org'&gt;Dojo&lt;/a&gt; j'avais la possibilité d'uploader la librairie sur une serveur ou bien d'utiliser la version "Online Cross Domain" hébergée par AOL.&lt;/p&gt;&lt;p&gt;Je ne pensais pas dire ça un jour, mais la version hostée par AOL fonctionne plutôt bien, les accès sont rapides etc... et surtout, pas besoin d'uploader ça quelque part. Comme quoi, y'a que les cons qui ne changent pas d'avis.&lt;/p&gt;&lt;p&gt;Bon aller sans plus attendre voici comment utiliser la version CDN de &lt;a href='http://dojotoolkit.org'&gt;Dojo&lt;/a&gt;. Il suffit d'ajouter ces quelques déclarations dans la section &lt;code&gt;head&lt;/code&gt; de votre page web. &lt;pre class="brush:html"&gt;&amp;lt;head&amp;gt;&lt;br /&gt;&lt;br /&gt;/* ... */&lt;br /&gt;&lt;br /&gt;/* utilisation de la version CDN de DOJO. */&lt;br /&gt;&amp;lt;script djConfig=&amp;quot;parseOnLoad: true, isDebug: false&amp;quot; src=&amp;quot;http://o.aolcdn.com/dojo/1.1.1/dojo/dojo.xd.js&amp;quot; type=&amp;quot;text/javascript&amp;quot;/&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;script language=&amp;quot;javascript&amp;quot; type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt; /* D&amp;#233;claration des objets/widgets Dojo */&lt;br /&gt; dojo.require(&amp;quot;dojo.parser&amp;quot;);&lt;br /&gt; dojo.require(&amp;quot;dojox.fx.easing&amp;quot;);&lt;br /&gt; dojo.require(&amp;quot;dojox.fx.scroll&amp;quot;);&lt;br /&gt;&amp;lt;/script&amp;gt;&lt;br /&gt;&lt;br /&gt;/* ... */&lt;br /&gt;&lt;br /&gt;&amp;lt;/head&amp;gt;&lt;/pre&gt;&lt;/p&gt; &lt;p&gt;Par la suite il vous suffit d'utiliser les nombreux widgets existants. En voici la &lt;a href="http://dojotoolkit.org/book/dojo-book-0-9/part-2-dijit/dijit-glance"&gt;liste complète&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Mais &lt;a href='http://dojotoolkit.org/'&gt;Dojo&lt;/a&gt; propose bien plus de chose que des widget, outre les facilités d'utilisations d'Ajax, aujourd'hui commune a beaucoup d'autres framework, &lt;a href='http://dojotoolkit.org/'&gt;Dojo&lt;/a&gt; embarque une grande quantité d'effets visuels. Pour en essayer un, essayez de cliquer sur le lien &lt;code&gt;top&lt;/code&gt; qui se trouve dans le footer de ce &lt;a href="http://mymemoryleaks.blogspot.com"&gt;blog&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Have fun.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1146316188254265608-2296189470619673282?l=mymemoryleaks.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mymemoryleaks.blogspot.com/feeds/2296189470619673282/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1146316188254265608&amp;postID=2296189470619673282' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1146316188254265608/posts/default/2296189470619673282'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1146316188254265608/posts/default/2296189470619673282'/><link rel='alternate' type='text/html' href='http://mymemoryleaks.blogspot.com/2008/06/dojo-et-blogger-ca-roule_06.html' title='Dojo et Blogger, ça roule.'/><author><name>Fabrice Michellonet</name><uri>http://www.blogger.com/profile/10201820062243684793</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_yYUu3sWKdtU/SE76j2im4AI/AAAAAAAACFA/OgO15yojzu8/S220/Fabrice_MICHELLONET.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1146316188254265608.post-5148744353465773244</id><published>2008-06-01T19:03:00.014+02:00</published><updated>2009-07-22T22:30:52.831+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Autre'/><title type='text'>Démarrage</title><content type='html'>&lt;p&gt;Alors voila l'aventure recommence pour moi, je me suis laissé tenté une fois de plus par l'envie d'ouvrir un blog technique. Il faut dire que cette fois-ci c'est &lt;a href="http://aurelien-koppel-pps.blogspot.com/"&gt;Aurélien&lt;/a&gt; qui m'a fait découvrir son blog ainsi que le système de template de Blogger. En réalité, c'est bien ce système customisable de template qui m'a donné envie de recommencer un blog. &lt;/p&gt; &lt;p&gt; Pour le contenu du blog vous y retrouverez mes découvertes aussi bien celles qui m'ont plus que celles qui m'ont déçues. &lt;/p&gt; &lt;p&gt; Bon, après ce petit billet d'introduction, je vous quitte afin de mettre au travail sur le template qui utilisera le framework &lt;a href="http://dojotoolkit.org/"&gt;Dojo&lt;/a&gt;; j'espère que vous apprécierez. &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1146316188254265608-5148744353465773244?l=mymemoryleaks.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mymemoryleaks.blogspot.com/feeds/5148744353465773244/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1146316188254265608&amp;postID=5148744353465773244' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1146316188254265608/posts/default/5148744353465773244'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1146316188254265608/posts/default/5148744353465773244'/><link rel='alternate' type='text/html' href='http://mymemoryleaks.blogspot.com/2008/06/demarrage_5777.html' title='Démarrage'/><author><name>Fabrice Michellonet</name><uri>http://www.blogger.com/profile/10201820062243684793</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_yYUu3sWKdtU/SE76j2im4AI/AAAAAAAACFA/OgO15yojzu8/S220/Fabrice_MICHELLONET.gif'/></author><thr:total>0</thr:total></entry></feed>
