Another .NET Blog

To content | To menu | To search

Tuesday 22 June 2010

[PostSharp] [Caliburn] - Appeler automatiquement NotifyOfPropertyChange pour les ViewModels

Dans cet article, je ne vais pas vous expliquer ce que sont Caliburn et PostSharp, leurs documentations et exemples respectifs le font déjà très bien, mais je vais expliquer comment créer un aspect que Postsharp va appliquer à des classes que nous définirons, et qui aura pour résultat d'implémenter l'interface INotifyPropertyChanged dans ces classes, et d'appeler automatiquement l'évènement PropertyChanged lorsque la valeur des propriétés publiques de ces classes va être modifiée.

Si vous connaissez déjà Postsharp, ou avez été regardé sur leur site, vous aurez sûrement remarqué qu'il existe déjà un aspect qui permet d'implémenter l'interface INotifyPropertyChanged, et d'appeler PropertyChanged à chaque changement de valeur de la propriété.

De même, si vous connaissez Caliburn, vous aurez également remarqué que les classes dont vous devez dériver pour implémenter vos ViewModels dérivent elles-même d'une classe abstraite nommée PropertyChangedBase, qui implémente INotifyPropertyChanged, et qui propose une fonction nommée NotifyOfPropertyChange, à laquelle vous passez comme paramètre le nom de la propriété qui a été modifiée.

L'aspect que je vais vous montrer va nous permettre de mixer ces 2 approches.

Continue reading...

Monday 17 May 2010

Rx: Nouvelle release

Une petite news rapide pour vous informer qu'une nouvelle version des Reactive Extensions a vu le jour vendredi dernier.

La release note se trouve ici. Et pour télécharger tout ça, c'est .

Et si vous ne connaissez pas cette API, n'hésitez pas à aller faire un tour ici, pour y découvrir les quelques articles que je lui ai consacré.

Thursday 13 May 2010

Rx: Exécuter une action de manière asynchrone

Pour clore le chapitre sur l'utilisation de Rx pour mon application de gestion de mises à jour, je vais terminer comme annoncé par vous montrer comment je lance les exécutables téléchargés de manière asynchrone, afin de ne pas bloquer le thread de la vue pendant l'installation.

Continue reading...

Wednesday 12 May 2010

Rx: Fusionner plusieurs Observable en un seul

Cet article est un prolongement de l'article précédent, puisqu'après avoir vu comment lancer le téléchargement de toutes les mises à jour et être notifié quand tout est terminé, nous allons cette fois voir comment récupérer une liste d'observables (chacun d'entre eux correspondant à l'installation d'une mise à jour), les fusionner en un seul, afin de pouvoir exécuter les mises à jour les unes après les autres, avec un arrête automatique dès lors qu'une mise à jour se passe mal.

Continue reading...

Tuesday 11 May 2010

Rx: Exécuter plusieurs observables et attendre qu'ils soient tous terminés

On continue avec la petite série d'articles Rx avec cette fois une nouvelle résolution de "problème". On a vu lors de l'article précédent comment ignorer les erreurs lorsque des adresses de téléchargement étaient invalides ou injoignables. Nous allons voir cette fois-ci comment lancer tous les téléchargements simultanément et comment attendre qu'ils soient tous terminés avant de les exécuter les uns après les autres pour les installer.

Continue reading...

Monday 10 May 2010

Rx: Opérateur Catch, ou comment ignorer des erreurs

Suite à mon article introductif sur les Reactive Extensions, je vais enchainer sur le même sujet une série d'articles (6 pour le moment sont prévus), bien plus courts que le dernier en date, et qui se focaliseront sur une manière de faire ou résoudre un problème précis que l'on peut rencontrer en utilisant cette API. Le premier article, ici-même, va s'attarder sur l'une des méthodes d'extension de Rx: Catch. Qui comme son nom le laisse supposer, a à voir avec les exceptions.

Continue reading...

Monday 12 April 2010

Introduction aux Reactive Extensions : Télécharger un fichier en asynchrone

J'ai déjà parlé à plusieurs reprises des reactives extensions, que l'on appelle plus familièrement Rx. Je me suis dit que ce serait une bonne idée que de vous les présenter plus en détail. Je ne vais pas écrire un article qui va tout vous expliquer depuis le début, car il existe déjà beaucoup de ressources. (ici, ici, ou bien ici, ou même encore ) Je me suis donc dit que ça serait peut-être une meilleure idée que de vous expliquer comment ça peut fonctionner grâce à un exemple concret. Et comme j'avais déjà un article expliquant comment réaliser une opération asynchrone en utilisant la TPL, j'ai repris cet exemple, en utilisant cette fois Rx.

Continue reading...

Thursday 8 April 2010

Follow me on twitter !!!

Petite news rapide pour vous dire que vous pouvez suivre les actualités de ce site via twitter, et être ainsi informés de la parution des nouveaux articles en live, ou presque.

Et ça se passe à cette adresse.

A bientôt !

Tuesday 6 April 2010

Aide à l'injection de dépendances pour Ninject grâce à une interface "fluent"

Je vais aujourd'hui vous présenter le résultat d'un refactoring de masse dans une série de tests unitaires, qui a permis d'accroitre très fortement la lecture des tests, et surtout leur compréhension.

La classe testée a pour but de gérer les mises à jour d'une liste de programmes installés sur un ordinateur. Cette classe est très "high-level" dans la mesure où elle permet d'aller récupérer la liste de toutes les mises à jour de toute une gamme de produits, de savoir pour chaque programme quelles sont les mises à jour à installer, puis bien évidemment de télécharger ces mises à jour et les installer.

Comme vous le voyez, cette classe consiste en beaucoup de sous-tâches, qui vont toutes communiquer avec le monde extérieur (internet notamment, pour l'obtention des mises à jours et leur téléchargement). Dans le but d'obtenir des tests unitaires les plus isolés possibles, j'en suis bien sûr arrivé à décomposer chacune de ces sous-tâches et à les identifier par des interfaces bien distinctes, pour lesquelles je laisse à Ninject le soin de les injecter comme il faut.

Rien que du très classique en somme. Le hic étant que cette classe nécessite du coup l'injection de beaucoup de dépendances (5 !) et que la mise en place des mocks dans chaque test rend le test trop long, et sa relecture difficile.

Voici donc une solution pour éviter ce genre de soucis. Solution qui se base, comme vous allez le constater, sur une hiérarchie de Providers Ninject, et une classe de construction d'un Module, qu'on rendra "Fluent".

Continue reading...

Monday 8 March 2010

Reactive Extensions

En fin de semaine dernière est sortie la dernière release des Reactive Extensions.

Beaucoup de changements sur la release note, mais on notera principalement la compatibilité .Net 4 RC.

A voir également, une vidéo de 22' sur Channel 9.

Source : Bart De Smet'S

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

- page 2 of 4 -