JetBrains supporte l'Open Source

Publié par Fabrice Michellonet sous le(s) label(s) le 27 avril 2010

Comme vous le savez sûrement, la version 5 de Resharper 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.

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 (Modified Closure), 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 GRATUITE...

Ouarf ouarf ouaf, s'écrit mon côté pessimiste...

Ça c'est de la bonne pub gratuite.

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...

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

Je vous l'accorde, ce jour la je devais être en mode Christophe... un peu beaucoup bougon! :)

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.

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.

Alors, il y a moins d'une semaine, je me lance, et soumet à la fameuse commission mon pet projet actuel (Claymore), 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.

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.

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.

Update [28 Avril 2010] : Jérôme m'a fait remarquer que mon lien vers l'exemple de Modified Closure était erroné. C'est corrigé.

Overriding et Shadowing de méthodes en IL.

Publié par Fabrice Michellonet sous le(s) label(s) le 23 avril 2010

En ce moment je fais joujou avec les opcodes CIL qui se cachent sous notre bon vieux C#.

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 :

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; }
    }

Du coté de la classe de base on obtient les metadata suivantes sur le getter :

non virtual :

.method public hidebysig specialname instance int32 get_Prop1() cil managed
virtual :
.method public hidebysig specialname newslot virtual instance int32 get_Prop2() cil managed
remarquez l'utilisation conjointes des metadata virtual et newslot, je reviendrais dessus juste après.

Côté classe dérivée on obtient cela :

non virtual :

.method public hidebysig specialname instance int32 get_Prop1() cil managed
new :
.method public hidebysig specialname instance int32 get_Prop2() cil managed
virtual new :
.method public hidebysig specialname newslot virtual instance int32 get_Prop3() cil managed

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.

Dans la classe dérivée, le shadowing non virtuel

public new int Prop2 { get; set; }
produit des metadata token strictement identiques à une propriété normale; et le shadowing virtuel produit un IL identique à propriété virtuelle.

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).

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.

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.

Interagir avec les pages ASP.NET avant l'Init.

Publié par Fabrice Michellonet sous le(s) label(s) , le 21 avril 2010

Au cours du développement de Claymore, pour la partie ASP.NET plus précisément, j'ai eu besoin de trouver un hook me donnant la possibilité d'interagir avec les pages avant les events que l'on trouve sur l'objet Page.

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 HttpModule je suis arrivé à la solution suivante :

using System;
using System.Reflection;
using System.Web;
using System.Web.UI;

namespace Claymore.Web
{
    /// <summary>
    /// 
    /// </summary>
    public class ClaymoreHttpModule : IHttpModule
    {
        #region Fields

        private HttpApplication _application;

        #endregion

        /// <summary>
        /// Initializes a module and prepares it to handle requests.
        /// </summary>
        /// <param name="context"> </param>An <see cref="T:System.Web.HttpApplication"/> 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;
        }


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

        /// <summary>
        /// Handle PostMapRequest event.
        /// </summary>
        /// <param name="sender"> </param>The sender.
        /// <param name="e"> </param>The <see cref="System.EventArgs"/> 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;
        }

        /// <summary>
        /// Handles the pre init event.
        /// </summary>
        /// <param name="sender"> </param>The sender.
        /// <param name="e"> </param>The <see cref="System.EventArgs"/> 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.
            }
        }
    }
}

L'un d'entre vous connaîtrait-il une solution équivalente à base de HttpHandler ou autre?

Benchmark WCF vs ASMX, Remoting, WSE, Enterprise Services.

Publié par Fabrice Michellonet sous le(s) label(s) le 5 avril 2010

Je relais assez peu souvent les infos glanées sur tel ou tel site, préférant vous montrer un peu de code :)

Ceci dit ce soir je fais une exception, en vous encourageant vivement a jeter un coup d'œil au benchmark des technos de mise en réseau que nous, développeurs .NET, avons à notre dispositions.

Le bench, étudie de manière approfondie chaque techno, et la compare dans un scenario viable et réaliste de leurs utilisations.

Je ne peux m'empêcher de vous donner une idée de ce qu'il en ressort :

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.

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