Another .NET Blog

To content | To menu | To search

Wednesday 3 March 2010

FXCop et CustomDictionary

Si vous utilisez FxCop, vous avez déjà peut-être été énervé de devoir supprimer manuellement tous les messages de type IdentifiersShouldBeSpelledCorrectly, vous disant que vous avez mal orthographié un mot.

Par exemple, dans mon projet actuel, tous mes namespaces commencent par Emidee, que l'ami FxCop ne reconnait bien évidemment pas.

Pour éviter ce travail fastidieux et pas franchement intellectuel, il est possible d'ajouter le(s) mot(s) en question dans le fichier CustomDictionary.xml situé dans le répertoire d'installation de FxCop. Le souci étant que si vous importez vos sources sur un autre PC, vous ne bénéficierez plus de cet avantage.

La solution à ce problème est toute simple: FxCop va recherche ce fichier CustomDictionary.xml dans 3 emplacements différents:

  1. dans le dossier d'installation de FxCop
  2. dans le dossier de l'utilisateur dont la session est ouverte (où exactement, j'avoue ne pas avoir cherché)
  3. dans le dossier où se trouve le fichier de projet .fxcop

Comme généralement vous placez le fichier de projet fxcop dans vos sources (comme ici par exemple), il vous suffit de créer un nouveau fichier CustomDictionary.xml au même endroit, et le tour est joué!

Et pour en terminer, voici la structure à respecter:

<?xml version="1.0" encoding="utf-8"?>
<Dictionary>
  <Words>
    <Unrecognized />
    <Recognized>
      <Word>Emidee</Word>
    </Recognized>
    <Deprecated />
  </Words>
  <Acronyms>
    <CasingExceptions />
  </Acronyms>
</Dictionary>

A bientôt!

Saturday 20 February 2010

Resharper 5 beta 2

Un petit billet pour vous informer, si vous ne l'étiez pas déjà bien sûr, de la disponibilité toute récente de Resharper en beta 2 s'il vous plait!

A télécharger donc d'urgence si vous bossez sous VS2010!

Wednesday 10 February 2010

Copie d'objets

La copie d'objets en C# est vraiment un vaste débat, dans lequel il est facile de se perdre au vu des différentes solutions proposées lorsque vous faites une petite recherche sur Google.

Je vais essayer dans cet article d'expliquer pourquoi il ne vaut mieux pas utiliser l'interface ICloneable du framework, les 2 types de copie réalisables en C#, et je finirai par un exemple concret qui mettra en évidence (qui le tentera du moins) quelle méthodologie appliquer en fonction de ce que vos classes ont à copier.

Continue reading...

[VS2010] La Release Candidate en téléchargement libre

Comme annoncé plus tôt dans la semaine, la release candidate de VS 2010 est désormais téléchargeable pour tous, à cette adresse.

Bon download et profitez bien de toutes les améliorations de cette version qui sera, je vous le rappelle, la dernière avant la version finale de la fin du mois d'avril!

[VS] Quelques astuces pour le debugger

Voici deux astuces qui je l'espère vous feront gagner du temps lorsque vous aurez à debugger vos applications.

Ne pas s'arrêter dans une propriété / fonction

La première astuce permet de gagner du temps lorsque vous suivez l'exécution d'un programme pas à pas, et que vous ne voulez pas, même en utilisant la commande Step Into (F11) aller dans le corps de propriétés / fonctions qui ne vous intéressent pas. L'exemple le plus flagrant étant les getters des propriétés, surtout quand il n'y a aucune logique dedans.

Par exemple, en utilisant le bout de code suivant:

using System;
using System.Diagnostics;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Employee emp = new Employee("Mike", 28);

            Console.WriteLine(emp.Name);
            Console.WriteLine(emp.Age);
            Console.ReadKey();
        }

        public class Employee
        {
            private string name;
            private int age;

            public Employee(string name, int age)
            {
                this.name = name;
                this.age = age;
            }

            public string Name
            {
                [DebuggerStepThrough]
                get { return name; }
            }

            public int Age
            {
                get { return age; }
            }
        }
    }
}

Si vous mettez un point d'arrêt à la ligne : Console.WriteLine(emp.Name);, et que vous appuyez sur F11, vous allez directement à la ligne suivante, sans passer par le corps du getter de Name. Si vous ré-appuyez sur F11, vous allez cette fois-ci vous retrouver à la ligne get { return age; }.

Très pratique donc pour éviter de se retrouver dans des fonctions sans-intérêt particulier. A noter également que même si vous mettez un point d'arrêt dans le corps d'une fonction marquée par cet attribut, le debugger ne s'y arrêtera pas.

Affichage personnalisé d'une variable

Voici une petite astuce qui peut se révéler très très pratique lorsque vous êtes en plein session de deboguage dans VS, et qui peut surtout vous faire gagner du temps, dès lors que vous devez inspecter souvent les même valeurs d'une instance d'un type.

Si l'on garde le morceau de code précédent, que l'on garde le point d'arrêt au même endroit, et que l'on passe la souris au dessus de la variable emp, voici ce qu'on obtient:

DebuggerDisplay_Before.png

Le debugger affiche le nom du type de la variable au dessous de laquelle se trouve le curseur de la souris. Si vous voulez accéder aux membres de cette variable, vous devez cliquer sur le petit +.

Si vous êtes intéressés uniquement par quelques membres de cette variable, ou si le type de la variable contient un petit nombre de membres et que vous voulez y avoir accès directement sans cliquer sur le +, voici une astuce qui vous sera certainement utile: il vous suffit d'ajouter un attribut à la déclaration de votre classe, comme suit:

[DebuggerDisplay("Employee : {Name} - {Age}")]
public class Employee
{
    //...
}

Et maintenant, lorsque vous passez la souris au dessus de la variable emp, comme précédemment, voici ce que vous deviez obtenir:

DebuggerDisplay_After.png

Il est bon également de savoir que cette astuce fonctionne également avec les classes dérivant de Employee. Si l'attribut DebuggerDisplay n'est pas ajouté aux classes dérivées, c'est l'affichage personnalisé de Employee qui sera utilisé. Mais si vous définissez cet attribut pour les classes dérivées de Employee, vous pourrez bien sûr faire référence aux propriétés de la classe Employee dans le constructeur de l'attribut:

[DebuggerDisplay("Boss : {Department} - {Name} - {Age}")]
public class Boss : Employee
{
    private readonly string department;

    public Boss(string department, string name, int age) : base(name, age)
    {
        this.department = department;
    }

    public string Department
    {
        [DebuggerStepThrough]
        get { return department; }
    }
}

En espérant que cela vous évitera quelques prises de tête lors de vos séances de debugging futures ;)

Tuesday 9 February 2010

VS2010 RC

Bonne nouvelle!

On apprend sur le blog de Jason Zander qu'il est possible depuis ce matin pour les abonnés MSDN et TechNet de télécharger la toute dernière version de Visual Studio 2010. Ce téléchargement sera disponible pour le commun des mortels dès demain.

Au menu, bien évidemment des améliorations des performances de l'IDE, qui étaient assez décriées:

In particular many of you pointed out areas of performance where we were not at parity with VS2008 and it was impacting your ability to adopt the product. Some of those areas of feedback included general UI responsiveness (including painting, menus, remote desktop and VMs), editing (typing, scrolling, and Intelisense), designers (Silverlight and WPF in particular), improved memory usage, debugging (stepping, managed / native interop), build times, and solution/project load.

A demain donc :)

Wednesday 3 February 2010

[Windows] Changement de layout du clavier intempestif

Je ne sais pas si ça ne vous est jamais arrivé, mais ça avait de quoi me rendre fou: le changement de layout du clavier qui passe en mode US, et ce de manière totalement imprévisible. Je me doutais bien qu'il devait s'agir d'un raccourci clavier de VS, mais je n'avais jamais trouvé lequel.

La seule solution que j'avais trouvé jusqu'à maintenant était de fermer l'IDE, et de le relancer. Donc plutôt lourd quand on est concentré sur ce qu'on fait, et que la solution prend du temps à charger.

Et bien bonne nouvelle, je viens juste de trouver quel est le fautif: la combinaisons de touches ALT+SHIFT !!!

Et donc refaire cette combinaison de touches corrige le souci. Enfin...

Edit: Bon en fait ce souci n'est en rien lié spécifiquement à VS, mais vient bien de Windows :s Merci à @Coldorak et à @Gimly81 pour leur explication sur twitter. Pou changer ce comportement, il suffit d'aller dans le Panneau de Configuration, puis dans les options de langages régionaux, de trouver un bouton Change keyboards, puis dans Advanced Key Settings de supprimer le shortcut ALT+SHIFT.

Merci à eux :)

Monday 25 January 2010

Classe Helper pour gérer soi-même le DoubleBuffering d'un contrôle Winforms

Le souci

J'ai récemment du implémenter le dessin d'une grille (comme dans l'éditeur de Visual Studio par exemple) sur un contrôle de type Panel. Innocemment, mon premier essai a été de m'abonner à l'évènement OnPaint du contrôle, et d'ajouter le code suivant:

private void Foo_Paint(object sender, PaintEventArgs e)
{
    using (Pen pen = new Pen(Color.Gray, 1))
        for (int x = 10; x < e.ClipRectangle.Width; x += 10)
            for (int y = 10; y < e.ClipRectangle.Height; y += 10)
                e.Graphics.DrawRectangle(pen, new Rectangle(new Point(x, y), new Size(1, 1)));
}

Je lance l'application, j'ai bien une grille qui est dessinée. Souci: dès que la form est rafraichie (quand on la redimensionne, ou qu'on change les propriétés d'un de ses contrôles enfants), la grille est redessinée, ce qui entraine de violentes lenteurs de l'affichage, avec du bon gros flickering.

La solution pour éviter ce souci est d'utiliser la technique du double-buffering.

La solution

Nous allons implémenter cette stratégie du double-buffer en créant une nouvelle classe, qui prendra en paramètre le contrôle à utiliser, ce qui nous permettra de réutiliser facilement et à moindre frais le code. L'idée est d'utiliser les classes BufferedGraphicsContext et BufferedGraphics pour dessiner l'arrière-plan du contrôle dans un buffer, et quand le contrôle doit se redessiner, on applique le contenu du buffer directement dans le contrôle. Et c'est donc en évitant le dessin progressif de l'arrière-plan du contrôle que l'on va éviter le scintillement.

Mais voici tout de suite la première version de notre classe:

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;

namespace Tools.GUI
{
    public class DoubleBuffer : IDisposable
    {
        private readonly Control control;
        private bool dirty;
        private BufferedGraphicsContext bufferedGraphicsContext;
        private BufferedGraphics bufferedGraphics;

        public DoubleBuffer(Control control)
        {
            this.control = control;

            bufferedGraphicsContext = new BufferedGraphicsContext();

            CreateGraphicsBuffer();

            this.control.SizeChanged += control_SizeChanged;
        }

        void control_SizeChanged(object sender, EventArgs e)
        {
            CreateGraphicsBuffer();
        }

        private void CreateGraphicsBuffer()
        {
            if (bufferedGraphics != null)
            {
                bufferedGraphics.Dispose();
                bufferedGraphics = null;
            }

            if (bufferedGraphicsContext == null || control.DisplayRectangle.Width <= 0 || control.DisplayRectangle.Height <= 0)
                return;

            using (Graphics graphics = control.CreateGraphics())
                bufferedGraphics = bufferedGraphicsContext.Allocate(graphics, control.DisplayRectangle);

            Dirty = true;
        }

        private bool Dirty
        {
            get { return dirty; }
            set
            {
                if (!value)
                    return;

                dirty = true;
                control.Invalidate();
            }
        }

        public void Dispose()
        {
            if (bufferedGraphics != null)
            {
                bufferedGraphics.Dispose();
                bufferedGraphics = null;
            }

            if (bufferedGraphicsContext != null)
            {
                bufferedGraphicsContext.Dispose();
                bufferedGraphicsContext = null;
            }
        }
    }
}

On commence par créer une nouvelle instance de la classe BufferedGraphicsContext, puis on crée l'instance de BufferedGraphics grâce à l'appel de la fonction CreateGraphicsBuffer, où l'on commence par supprimer l'instance existante, puis où l'on crée effectivement la nouvelle instance grâce à un appel à la fonction Allocate de BufferedGraphicsContext, qui prend en paramètre le Graphics du contrôle, ainsi que le rectangle correspondant à la surface affichée du contrôle. Vous aurez remarqué que l'on ne crée pas le buffer si le contrôle a une largeur ou une hauteur égale à zéro.

Comme on a un nouveau buffer, on met le flag Dirty à true, qui aura pour conséquence de forcer un ré-affichage du contrôle via l'appel de Invalidate() (dans le setter de Dirty). Dans le constructeur de la classe, on s'abonne également à l'évènement SizeChanged du contrôle, car nous devons toujours avoir un buffer qui ait les mêmes dimensions que le contrôle.

C'est bien beau, mais nous n'affichons toujours rien pour le moment. Nous allons corriger ça de suite, on commençant par nous abonner à l'évènement OnPaint du contrôle, dans le constructeur de la classe:

public DoubleBuffer(Control control)
{
	this.control = control;

	bufferedGraphicsContext = new BufferedGraphicsContext();

	CreateGraphicsBuffer();

	this.control.SizeChanged += control_SizeChanged;
	this.control.Paint += control_Paint;
}

Nous allons ensuite définir la fonction control_Paint:

void control_Paint(object sender, PaintEventArgs e)
{
	if (bufferedGraphics == null)
	{
		Draw(e.Graphics);
		return;
	}

	if (Dirty)
	{
		Dirty = false;
		Draw(bufferedGraphics.Graphics);
	}

	bufferedGraphics.Render(e.Graphics);
}

Le fonctionnement du double buffer se fait ici: si on n'a pas de buffer (par exemple, le contrôle a sa largeur ou sa hauteur qui est nulle) , on va dessiner le contenu de l'arrière-plan du contrôle normalement, en passant à la fonction Draw le Graphics du contrôle, auquel on accède grâce à la propriété Graphics de PaintEventArgs. Si par contre on a un buffer, on commence par regarder l'état du flag Dirty. S'il est à true, c'est que l'on doit redessiner le buffer, ce qui est fait en passant la propriété Graphics de la classe BufferedGraphics. Et pour terminer, on appelle la fonction Render de BufferedGraphics, qui va écrire le contenu du buffer directement dans l'objet Graphics donné en paramètre, c'est à dire dans le Graphics du contrôle, provoquant donc l'affichage du contrôle.

Nous faisons mention dans le code précédent d'une fonction Draw, que voici:

private void Draw(Graphics graphics)
{
	if (control.ClientRectangle.Width <= 0 || control.ClientRectangle.Height <= 0)
		return;

	using (SolidBrush backBrush = new SolidBrush(control.BackColor))
		graphics.FillRectangle(backBrush, control.ClientRectangle);
}

Tout ce que fait cette fonction pour le moment, c'est juste de remplir l'arrière-plan du contrôle avec la couleur définie par la propriété BackColor. Pas très intéressant donc. Il serait bien de pouvoir définir des fonctions à exécuter dans la fonction Draw, afin de personnaliser l'affichage, et de profiter du double buffering mis en place. Nous allons arriver à ça en utilisant une liste d'actions, qui seront exécutées à la fin de la fonction Draw. Les actions étant enregistrées par l'utilisateur de la class DoubleBuffer via une fonction RegisterPaintAction.

Nous allons commencer par ajouter un nouveau membre à notre classe:

private readonly List<Action<Graphics, Rectangle>> paintDelegates = new List<Action<Graphics, Rectangle>>();

Puis nous exécutons la liste des actions dans la fonction Draw:

private void Draw(Graphics graphics)
{
    if (control.ClientRectangle.Width <= 0 || control.ClientRectangle.Height <= 0)
        return;

    using (SolidBrush backBrush = new SolidBrush(control.BackColor))
        graphics.FillRectangle(backBrush, control.DisplayRectangle);

    paintDelegates.ForEach(action => action(graphics, control.DisplayRectangle));
}

Et nous créons les fonctions d'enregistrement et de dés-enregistrement des actions (utile pour par exemple afficher ou pas la grille):

public void RegisterPaintAction(Action paintDelegate)
{
    if (paintDelegate == null)
        return;

    paintDelegates.Add(paintDelegate);

    Dirty = true;
}

public void UnregisterPaintDelegate(Action paintDelegate)
{
    if (paintDelegates.Remove(paintDelegate))
        Dirty = true;
}

On met le flag Dirty à true quand on ajoute une nouvelle action pour forcer un ré-affichage du contrôle immédiat.

Et voilà! Et pour utiliser tout ça, un petit exemple d'affichage de grille dans l'arrière-plan de la form:

using System.Drawing;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        private readonly DoubleBuffer doubleBuffer;
        
        public Form1()
        {
            InitializeComponent();

            doubleBuffer = new DoubleBuffer(this);

            doubleBuffer.RegisterPaintAction((graphics, rectangle) =>
                                                   {
                                                       using (Pen pen = new Pen(Color.Gray, 1))
                                                           for (int x = 10; x < rectangle.Width; x += 10)
                                                               for (int y = 10; y < rectangle.Height; y += 10)
                                                                   graphics.DrawRectangle(pen, new Rectangle(new Point(x, y), new Size(1, 1)));
                                                   });
        }
    }
}

C'est tout pour cette fois ;) N'hésitez pas à me laisser vos impressions ou vos retours sur ce code!

PS: je joins à cet article le code complet de la classe DoubleBuffer.

Friday 22 January 2010

Configuration d'un serveur d'intégration continue - [Partie 5] - Bonus

Nous voici enfin arrivés à la dernière partie de cette série d'articles relatifs à la configuration d'un serveur d'intégration continue avec Hudson. Dans cette très courte partie, je vais vous présenter 2 plugins à installer dans Hudson, qui permettront d'avoir sur la page d'accueil de votre projet un résumé des tâches à faire et bugs à résoudre, et également la liste de tous les warnings émis par le compilateur lors de... euh... la compilation :)

Continue reading...

Thursday 21 January 2010

Rx Framework

Ça fait quelques temps que je vois fleurir sur internet des références de plus en plus nombreuses aux Reactive Extensions, plus communément appelé Rx. Je ne savais pas trop ce que c'était (j'en sais un peu plus maintenant, mais le sujet a l'air d'être... disons, vaste), et c'est 2 posts (ici et ) sur le blog de Jon Skeet qui m'ont enfin décidé à aller voir sur devlabs de quoi il en retournait.

Et je dois bien dire que je suis bluffé. Mais vraiment. Je crois bien que l'on a ici un framework qui devrait radicalement changer notre manière de travailler. Alors bien sûr j'en ai vu trop peu pour être réellement objectif et constructif sur le sujet, et je vais regarder quelques vidéos sur Channel9 sur le sujet avant de m'en faire une idée précise, mais je suis déjà sous le choc.

Pour vous faire une idée de ce qu'est la "bête", je vous recommande plus que chaudement de commencer par cette vidéo, où l'un des développeurs de la librairie (accessoirement aussi l'un des co-fondateurs de LINQ, ça aide) nous explique grossièrement l'objectif de Rx. Et avant de regarder la pléthore de vidéos disponibles sur Channel9 ( ce que je dois encore faire également), jetez tout de suite un oeil à cette vidéo, qui est un cas concret du fonctionnement de Rx, et où on se rend compte de sa puissance à travers un exemple concret: comment implémenter du drag 'n drop d'un contrôle WPF dans une fenêtre au runtime.

Mais je dois vous laisser, j'ai encore BEAUCOUP de vidéos à aller regarder, là, maintenant ;)

Tuesday 19 January 2010

Configuration d'un serveur d'intégration continue - [Partie 4] - NCover

Partie 4 de cette série d'articles, qui va cette fois se concentrer sur la couverture du code par les tests unitaires, grâce à un outil nommé: NCover. Je ne rentre dans dans les détails sur ce qu'est capable de faire cet outil, leur site est très fourni à ce niveau là. Par contre pour ceux qui ne connaissent pas du tout, cet outil va vous permettre de lancer vos tests unitaires, et va analyser durant l'exécution des tests quelles sont les fonctions de votre code à tester qui sont appelées, et surtout celles qui ne le sont pas. Ce qui permet de savoir où orienter les tests unitaires afin de couvrir l'ensemble du code.

Mais trêve de blablas, et rentrons dans le vif du sujet.

Continue reading...

Configuration d'un serveur d'intégration continue - [Partie 3] - FxCop

Poursuivons cette série d'articles en nous attardant désormais sur l'analyse du code des assemblies grâce à un outil que vous devez tous connaître (et si ce n'est pas le cas, je vous enjoins expressément à vous y intéresser): FxCop. D'une manière similaire à ce que nous avons fait auparavant avec les tests unitaires, nous allons là aussi "programmer" l'exécution de l'analyse dans le fichier NAnt, puis nous allons configurer Hudson pour afficher les résultats de cette analyse directement sur la page du projet.

Continue reading...

Friday 15 January 2010

Configuration d'un serveur d'intégration continue - [Partie 2] - Tests unitaires

Après avoir vu dans la première partie comment installer Hudson, configurer notre premier job et notre premier fichier NAnt, nous allons maintenant voir comment lancer automatiquement dans le processus de compilation l'exécution de tous les tests unitaires de la solution, bien entendus créés avec le framework de test xUnit.

Continue reading...

Thursday 14 January 2010

Configuration d'un serveur d'intégration continue - [Partie 1] - Les bases

On trouve sur internet un paquet de tutoriaux sur la configuration de divers serveurs d'intégration continue, basés sur des solutions différentes (TeamCity, Hudson, Cruise Control.NET...), avec des options différentes (FxCop, avec ou sans tests unitaires...). Le problème est que ces tutoriaux ciblent tout le temps .NET 3.5 ou 2.0 (normal me direz vous) et que les "options" proposées ne me conviennent pas, notamment concernant les tests unitaires (Personne n'utilise donc xUnit?)

Je me suis donc efforcé de faire fonctionner un serveur d'intégration continue qui remplirait les objectifs suivants:

  1. Framework ciblé : .NET 4.0
  2. Librairie de tests unitaires : xUnit
  3. Utilisation d'outils d'analyse de code : FxCop
  4. Couverture de code : nCover

Et je me propose donc de vous en relater les étapes lors de cette série d'articles.

Continue reading...

VS2010 et .NET 4 pour le 12 Avril prochain?

Vu sur developpez.com, les sorties de Visual Studio 2010 et .NET 4 prévues pour le 12 Avril prochain, une RC en Février ?

Le compte à rebours est désormais lancé!

Nouvelle release de Code Contracts

Hier soir est sortie une nouvelle release de Code Contracts, à télécharger ici.

Pour info, la release note:

Release 1.2.30113.1 (Jan 13, 2010) Contracts

  • Silverlight 4 support added, Silverlight2 dropped.
  • We now have a set of contract reference assemblies for the different target frameworks (3.5, 4.0, Silverlight 3.0, Silverlight 4.0). This allows contracts on newer APIs and avoids problems where the rewriter added the wrong references to the target assembly.
  • Contract invariant methods now must be private.
  • Invariants on auto properties are turned into pre and post conditions of the corresponding setter and getter. This permits using auto properties with contracts.
  • Added more contracts to System.Linq, System.Net, System.Collections, System.Data, System.Math namespaces
  • Fixed issues of referencing v3.5 assemblies with contracts from v4.0 projects
  • Tweaks to extraction of contracts from VB constructors

Runtime Checker

  • Makes sure contract invariant methods are not called directly
  • Object invariants are now delayed until the end of the constructor to avoid checking them prematurely
  • Fixes to contract inheritance that would generate bad IL.
  • Avoid FxCop warnings about catching all exceptions in OldValue expressions
  • Initial support for ContractIgnoredAttribute added (see documentation)
  • Fix in rewriting attributes with arrays of enums
  • Fixed codegen issues when removing Assert/Assumes from code

Documentation Generation

  • Fixed path problems
  • Fixed inheritance problems

Static Checker

  • Improved handling of IsNan
  • Improved error messages now include the condition in all cases (not just for other assemblies)
  • Improved interval analysis
  • Improved handling of box operations
  • Squigglies now work in VS2010
  • Fixed handling of unicode error messages in the output
  • Better handling of IntPtr and UIntPtr
  • Better handling of inferred mutations at method calls
  • Masking of warnings at the assembly level using SuppressMessage now supported for global warnings

Monday 11 January 2010

Visual Studio 2010: "The application cannot start"

Surprise!

Je lance Visual Studio 2010, et alors que tout fonctionnait parfaitement bien vendredi dernier, aujourd'hui monsieur me fait un caprice et ne veut plus s'ouvrir, et me donne un message d'erreur assez laconique: "The application cannot start"

Après une petite recherche sur le web, il s'avère que cette erreur peut être due à un fichier de préférences corrompu, ou bien à une tentative d'import de police non TrueType créée avec une version de VS inférieure. Comme je n'ai jamais approché de près ou de loin ce deuxième point, je me suis donc douté que ça devait bien être le fichier des préférences (Elémentaire mon cher watson).

La solution proposée, qui a très bien fonctionné pour moi: lancer VS via la ligne de commande en utilisant le flag resetuserdata:

devenv /resetuserdata

Pour info, l'exécutable de VS2010 se trouve dans ce dossier : ''C:\Program Files\Microsoft Visual Studio 10.0\Common7\IDE''

Bien évidemment, attendez vous à perdre toutes vos customisations. Pensez donc à les sauvegarder en copiant le fichier CurrentSettings.vssettings qui se trouve ici : “%USERPROFILE%\Documents\Visual Studio 2010\Settings !

Saturday 9 January 2010

VS2010: Nouvelle page de résumé pour le profiler

Vu sur le blog de l'équipe en charge du développement du profiler pour VS2010, les nouveautés concernant la page de résumé du profiling d'une application. A lire ici.

A lire également ici, une sorte d'introduction à comment lancer une séance de profiling grâce au raccourci clavier ALT+F2

Et pour finir, leur tout dernier article explique comment lancer une session de profiling sur une série de tests unitaires.

Bonne lecture!

Tuesday 5 January 2010

VS2010 / xUnit / Resharper : enfin, ça marche!

Bonne nouvelle!

Cela faisait un moment que je tentais désespérément de lancer des tests unitaires sous VS2010 avec xUnit et Resharper 5, sans succès, comme vous vous en doutez. La seule solution avait été de recompiler le GUI de xUnit en .NET 4 et de l'utiliser pour les tests. Ce que je ne trouve pas très pratique, dans la mesure où ça oblige à jongler entre plusieurs applications. C'est toujours plus simple de rester dans son environnement de travail.

Eh bien c'est désormais possible. C'est extrêmement simple, en voici la procédure:

  1. Télécharger et installer la nouvelle version de Resharper 5.0, qui est désormais en Beta.
  2. Télécharger la dernière version de xUnit Contrib
  3. Installer xUnitContrib

Une fois ces 3 étapes faites, lancez VS2010 et ô surprise:

Preview_xUnit_R__VS2010.png

En voilà une bonne nouvelle pour une rentrée de Vacances :)

Monday 21 December 2009

Go go PEX et Code Contracts !!!

Si vous ne connaissez pas PEX ou Code Contracts, bonne nouvelle! Il existe un podcast en français (oui oui!) qui présente très succinctement ces 2 nouveaux outils prévus pour .NET 4.0 qui vous permettront de faciliter vos développements en TDD.

En effet, Code Contracts vous permet de définir dans le corps de vos fonctions des contrats (étonnant non?) qui vont porter sur les valeurs d'entrée et de sortie de vos fonctions. Ça vous permet d'éviter toutes ces séries de tests rébarbatives vérifiant par exemple que ArgumentNullException est bien lancée quand vous passez un null, ou qu'une fonction ne retourne jamais null. De quoi alléger un peu les test.

PEX quant à lui va vous permettre d'automatiser l'appel des fonctions avec des valeurs plus ou moins aléatoires, ce qui va vous permettre de voir dans quelle mesure vos tests unitaires couvrent bien l'intégralité des possibilités d'erreur (ou non) lorsque vous utilisez ces fonctions.

2 nouveaux outils que je trouve vraiment très intéressant et pour lesquels je pense faire prochainement des articles lorsque je commencerai à les utiliser.

Via Coq Blog.

- page 2 of 4 -