Déménagé!

J'ai déménagé! Me voici maintenant propriétaire d'une belle maison à Charlesbourg. Le déménagement a très bien été, grâce à une dixaine d'amis et membres de ma famille qui nous ont aidé.

Nous sommes maintenant presque complètement installés, et nous pouvons enfin profiter de la tranquillité qu'apporte une maison qui nous appartiens.

Voici quelques photos que j'ai prises plus tôt cette semaine:

Est-ce que la culture devrait apparaître dans l'URL ?

Récemment j'ai assisté à une conférence sur ASP.NET MVC donnée par Scott Hansleman dans le cadre d'un événement de la CUNQ. Pendant sa présentation, Scott a mentionné la globalisation d'applications, et son opinion sur le sujet.

Selon lui, la culture (en-US, fr-CA, etc.) n'a rien à faire dans l'URL. L'application devrait se fier exclusivement sur les paramètres du navigateur. Il va même jusqu'à dire que dans la majorité des cas, il est inutile d'offrir aux visiteurs l'option de sélectionner leur langue préférée (par exemple avec des petits drapeaux représentant les différentes cultures disponibles).

Je n'ai pu m'empêcher d'intervenir. Selon moi, pour certains usagers, la possibilité de changer la langue active sur un site est très utile. Il serait fâchant pour les usagers de devoir modifier la configuration de leur navigateur chaque fois qu'ils désirent changer la langue d'un site.

Scott répond à cela que la proportion d'usagers susceptibles de vouloir ce type de fonctionnalité est si petite qu'elle ne justifie pas d'encombrer l'interface, ni même l'URL.

D'une part, je comprends son point. Pourquoi rendre l'URL moins "amicale" pour un paramètre de la sorte? Toutefois, j'utilise moi même ce type de fonctionnalité assez fréquemment, et je connais plusieurs personnes qui pensent comme moi. Il est parfois aussi pratique de pouvoir changer la langue du site simplement en modifiant "fr" pour "en" dans l'url, ou encore d'avoir la possibilité de faire un lien direct à une page dans une langue précise.

Je crois qu'un compromis est possible. La partie de l'URL déterminant la langue devrait être optionnelle. Si elle est spécifiée, le site utilise cette langue, autrement, il se fie sur les paramètres du navigateur.

Je vais probablement créer un petit exemple d'une façon de faire cela avec ASP.NET MVC. Ce sera une bonne façon de voir par la même occasion s'il est simple de concevoir des sites multilingues avec ce framework. En attendant, qu'en pensez-vous? Quelle est votre opinion là dessus?

Nearly Free Speech

Depuis sa mise en ligne, mon site était hébergé sur mon ordinateur personnel, chez moi. C'était loin d'être idéal!

Premièrement il y a la question évidente de la disponibilité: si mon ordinateur est fermé, ou si ma connexion Internet fait défaut, le site n'est pas accessible. Pas très intéressant...

Ensuite, mon fournisseur de services Internet est Vidéotron, et ils ont la fâcheuse particularité de bloquer le port 80. Donc, pour héberger mon site chez moi, j'ai du avoir recours à un hack: J'ai configuré IIS pour écouter sur le port 81 au lieu de 80, et lorsqu'une requête arrivait à www.leddt.com, j'effectuais une redirection, grâce à EveryDNS.net, vers home.leddt.com:81. Encore une fois, il ne s'agit pas de la meilleure approche.

Malgré tous ces problèmes, m'occuper moi même de l'hébergement avait un avantage très important: le prix. Effectivement, ça ne me coûtait absolument rien pour héberger le site chez moi. Je ne voulais pas être pris avec des factures mensuelles pour un site qui ne reçoit pratiquement pas de trafic.

NearlyFreeSpeech.Net

Aujourd'hui j'ai fait le grand saut, et j'ai transférer l'hébergement de leddt.com vers NearlyFreeSpeech.Net. Leur politique de prix correspond parfaitement à mes besoins: je paie pour ce que j'utilise, et pas un sous de plus.

Les prix pour la bande passante commencent à 1$ pour 1 Go, et vont en diminuant selon l'utilisation. L'espace disque est 0.01$ par Mo par mois. Vous pouvez avoir une base de données MySQL pour 0.01$ par jour. Mon site, pour le moment, totalise environ 500 Ko, n'utilise pas de base de données et ne reçoit presque pas de trafic, moins de 100 Mo par mois. Cette utilisation me coûtera donc moins de 0.10$ par mois.

10 sous... J'ai déposé 10$ dans mon compte sur NFSN, et ça devrait me suffire pour quelques années, si mon utilisation reste sensiblement la même. À ce prix, à quoi bon s'en passer?

NFSN offre aussi gratuitement le service de DNS. Ce service est complet et n'a pas de limite, le rendant encore plus intéressant que EveryDNS. Il n'est pas possible de l'utiliser pour gérer une adresse IP dynamique, comme avec eDNS, mais un simple CNAME pointant sur mon compte dyndns fait très bien l'affaire.

Le seul "problème", c'est qu'ils n'offrent pas l'hébergement .Net. C'est compréhensible puisque leurs serveurs sont évidement sous linux. En tant que développeur spécialisé en .Net, c'est dommage, mais pour le moment je n'en ai pas besoin. Mais si un jour j'ai une application asp.net à héberger, je devrai trouver une autre solution.

À part de cela, je n'ai eu aucune difficulté à utiliser ce service jusqu'à maintenant. Les serveurs sont rapides, l'interface d'administration est simple et la documentation est bien écrite. Si vous cherchez de l'hébergement abordable, je ne peux que vous conseiller NearlyFreeSpeech.Net.

Écrire des tests unitaires pour une application ASP.NET

S'il y a une méthodologie de développement qui a gagné beaucoup de popularité ces dernières années, c'est l'écriture de tests unitaires.

De bons tests unitaires sont indispensables puisqu'ils offrent un filet de sureté dans le cadre de la maintenance d'applications. Si votre couverture de code est suffisante, et que vos tests sont correctement conçus, vous pourrez faire des modifications au code sans avoir peur de briser d'autres fonctionnalités par la même occasion.

Il existe de nombreux Framework de tests unitaires pour .NET, tel NUnit, xUnit ou MSTest. Chacun ont leurs forces et faiblesses, mais une lacune commune à travers ces différents outils est la difficulté de tester des applications ASP.NET.

Le principal problème pour ce genre de test est l'absence du HttpContext dans le cadre d'un test unitaire. Admettons que vous avez créé des classes pour écrire et lire des valeurs dans la session d'un usager, comment tester cela si HttpContext.Current est null lors des tests?

J'ai rencontré ce problème pour le projet sur lequel je travail présentement. Après quelques essais infructueux à créer moi même une instance de HttpContext, j'ai trouvé une solution simple et élégante. HttpSimulator, par Phil Haack, est une composante très bien faite qui permet de simuler l'état d'une application pendant une requête ASP.NET.

Son usage est extrêmement simple :

// Cet exemple utilise MSTest

[TestMethod]
public void SetAndRetreiveBasketID()
{
    string expected = "Sample value";
    string actual;

    using (new HttpSimulator().SimulateRequest())
    {
        SessionHelper.BasketID = expected;
        actual = SessionHelper.BasketID;
    }

    Assert.AreEqual(expected, actual);
}

Bref, tout le code situé à l'intérieur du using peut utiliser HttpContext.Current. Il est aussi possible de définir des paramètres afin de spécifier une URL particulière, ou encore pour simuler le POST d'un formulaire.

Malheureusement, certaines propriétés du HttpContext demeurent null même en utilisant HttpSimulator, et donc il se peut que vous ne puissiez pas tester toutes les fonctionnalités. Dans certains cas, il est possible de modifier légèrement HttpSimulator pour inclure ce dont vous avez besoin, mais dans d'autres cas, ça peut être plus compliqué.

Malgré tout, ce simulateur devrait vous aider à tester une bonne partie de votre code. Notez que cet outil n'est pas conçu pour tester vos pages ASPX. Il sert à tester le code qui a besoin d'un HttpContext pour fonctionner. Pour tester vos pages, il existe d'autres outils.

Petite mise à jour

J'ai été plutôt silencieux ces dernières semaines. La raison est que je suis débordé dernièrement.

J'ai déménagé, ce qui a demandé beaucoup de mon temps. L'appartement commence enfin à avoir l'air d'un endroit habitable!

Quelque chose est arrivé qui m'a beaucoup fâché: 2 jours après avoir emménagé, je me suis fait voler >:(. Ils ont pris mon ordinateur portable, des DVD, bijoux... Au total pour près de 3000$. Donc en plus d'être très occupé à remettre de l'ordre dans nos affaires, nous avons du nous occuper de remplir un rapport de police et de faire une réclamation à nos assurances. Au moins, il y a maintenant toujours quelqu'un à l'appartement d'en dessous, donc ce genre de chose ne devrait plus se produire.

Je suis également beaucoup occupé par mon travail. Ces temps-ci, je passe mes journées à corriger des bugs ou à écrire des tests unitaires. Il ne s'agit pas du travail le plus passionnant qui soit, et donc quand je termine ma journée, j'essais de me changer les idées et j'évite mon ordinateur!

Malgré tout, je vais essayer d'écrire un peu plus fréquemment. Attendez-vous à un autre article d'ici quelques jours.

Parallel Framework Extensions

De plus en plus de personnes sont maintenant équipées de processeurs Dual Core. Les Quad Core commencent aussi à gagner de la popularité, et même les processeurs à huit coeurs (Octo Core ?) deviennent réalité. Il est très facile d'imaginer un processeur seize coeurs dans chaque nouvel ordinateur d'ici seulement quelques années.

Tout ceci est bien beau, mais pour prendre avantage de toute cette puissance, il faut que les applications soient programmées pour utiliser plusieurs threads. Ceci peut devenir très compliqué avec les techniques actuelles, et représente parfois trop de travail pour justifier les résultats. Mais lorsque les processeurs à multiples coeurs deviendront chose du commun, ces résultats seront de plus en plus impressionnants.

Afin de diminuer la complexité de la programmation multi-thread, et ainsi favoriser le développement de ce type d'applications, Microsoft travail sur une librairie très intéressante nommée Parallel Framework Extensions (PFX). Cette librairie offre des façons très simples d'accomplir certaines tâches communes dans le monde de la programmation parallèle.

Par exemple, supposons que vous avez une collection d'objets sur lesquels vous désirez effectuer un traitement. Une implémentation naïve de cela pourrait ressembler à ceci :

private void DoManipulationOnFooList(IList<Foo> data)
{
    foreach (Foo f in data)
    {
        // Do something with f
    }
}

Ce code est très simple et parfaitement acceptable lorsque l'ordinateur n'a qu'un seul processeur. Toutefois, une machine à quatre coeurs ne pourra utiliser que le quart de sa capacité pour traiter ce code.

Une meilleure implémentation serait d'utiliser le ThreadPool.

private void DoManipulationOnFooList(IList<Foo> data)
{
    foreach (Foo f in data)
    {
        ThreadPool.QueueUserWorkItem(new WaitCallBack(delegate(object arg)
        {
            Foo foo = (Foo)arg;
            // Do something with foo
        }, f));
    }
}

De cette façon, plusieurs coeurs seront utilisés. Toutefois, le code est moins élégant que la première version, et quelques problèmes peuvent survenir. Qu'arrive-t-il si une exception a lieu lors du traitement de l'un des item? Plusieurs détails doivent être considérés pour utiliser le ThreadPool, et cette méthode pourrait facilement devenir très compliquée. De plus, pour obtenir le même comportement que la première version du code, il faut ajouter un mécanisme pour empêcher DoManipulationOnFooList de retourner tant que tout le travail n'est pas terminé.

Avec PFX, une implémentation complète et très efficace de cette situation pourrait ressembler à ceci :

private void DoManipulationOnFooList(IList<Foo> data)
{
    Parallel.ForEach<Foo>(data, delegate(Foo f) 
    {
        // Do something with f
    });
}

Notez qu'il ne s'agit peut-être pas de la syntaxe exacte. Je n'ai pas trouvé d'exemple concret de la méthode ForEach.

Beaucoup plus simple n'est-ce pas? Le code est très semblable à la première version, mais celui-ci utilisera efficacement tout les processeurs disponibles. La liste d'objets sera séparée entre les différents coeurs, qui travailleront chacun de leur côté. Si un processeur termine son travail avant les autres, il ira voler du travail aux autres. Les exceptions seront gérées d'une manière prévisible, et la méthode ne retournera que lorsque tout le travail sera terminé.

Bien entendu, PFX ne s'arrête pas là. Bien que cette façon de faire sera satisfaisante dans plusieurs cas, des problèmes plus compliqués demandent des méthodologies différentes. Pour ces cas, il est possible de descendre d'un niveau d'abstraction et d'utiliser des composantes plus flexibles.

Ces concepts de parallélismes ont aussi été adapté à LINQ. Avec PLINQ, vous pourrez prendre avantage de tous les processeurs de l'ordinateur lors de vos requêtes LINQ et ce, en ajoutant simplement .AsParallel() à celles-ci.

Il est difficile d'en dire plus sur ce sujet car très peu de documentation existe pour le moment. Toutefois, il s'agit d'une technologie très intéressante, et je crois bien que tous les développeurs devraient se familiariser avec cela le plus tôt possible. Je vous suggère de commencer par ce vidéo sur Channel9 qui présente un survol des bases de PFX et PLINQ.

Mise à jour, 13 mai 2008: J'ai réalisé que certains liens dans cet article ne fonctionnaient plus. Je les ai remplacés par des liens fonctionnels. Remarquez qu'un CTP de Parallel Extensions est maintenant disponnible à télécharger.

ReSharper

Un autre outil que j'ai récemment découvert est ReSharper. Il s'agit d'un add-in pour Visual Studio qui aide les développeurs à créer du code à la fois robuste et élégant.

Bien qu'il ne soit pas gratuit, ses nombreuses fonctionnalités le rende très intéressant. Son slogan, "The Most Intelligent Add-In To Visual Studio", semble prétentieux, mais après quelques jours à utiliser cet add-in, je ne crois pas que vous voudrez vous en passer.

Je ne peux pas énumérer ici tout ce qu'il peut faire, mais voici un aperçu.

ReSharper analyse votre code et indique les endroit où il semble y avoir des erreurs ou problèmes. Par exemple, si vous retournez un object au lieu d'une string dans une méthode, le code sera souligné et vous serez averti de cela avant même d'avoir compilé. Ou encore, si vous utilisez String.Format() et que vous utilisez plus de paramètres que vous ne fournissez d'arguments, les paramètres en trop seront soulignés.

Pour la plupart des problèmes identifiés, ReSharper offre des corrections automatiques. Ainsi, dans le cas du mauvais type de retour pour une méthode, un menu vous permettra d'insérer un cast à l'endroit approprié en seulement deux clics.

Ajoutez à cela de l'autocomplétion, des outils de refactoring avancés, de nombreux raccourcis claviers très utiles et beaucoup plus encore, et vous avez devant vous un outil qui augmentera à coup sur votre productivité.

ReSharper supporte C# et VB, ainsi qu'ASP.NET, XML et XAML. Je vous invite fortement à télécharger la version d'essais, et de convaincre votre employeur d'investire dans cet outil.