DevWeek 2005 comme si vous y étiez Par Bruno Boucard  (boucard.bruno@free.fr)

La plus grande conférence indépendante du Royaume Uni dédiée au développement Microsoft a eu lieu à Londres du 21 au 25 février 2005. Bruno Boucard, notre envoyé spécial pour l'occasion y était et vous relate les différentes sessions qu'il a pu suivre. Un compte rendu dense mais instructif. 

a plus grande conférence indépendante du Royaume Uni dédiée au développement Microsoft a eu lieu à Londres du 21 au 25 février 2005, dans le « Business Design Centre ». Ce bâtiment très moderne, est situé dans le quartier Islington, non loin des quartiers de La City et de West End. Pour sa 8ième édition, la conférence DevWeek 2005, organisée par la société Bearpark Publishing (Visual Systems Journal), a réuni un plateau de speakers prestigieux répartis en 72 sessions et 14 ateliers.

En réalité DevWeek incorpore aussi la conférence SQL Server DevCon. La première était donc dédiée aux développeurs .NET, la seconde aux développeurs SQL Server. Enfin, notons qu’a l’instar des autres conférences techniques d’aujourd’hui, DevWeek proposait des journées optionnelles de type Workshop consacrées à un sujet particulier : une journée de post conférence le 21 et une journée de post conférence.

Première journée

Technical Keynotes : What’s new in Visual Studio 2005

Comme c’est souvent le cas dans les conférences techniques, le célèbre Keynotes d’ouverture permet de donner le ton des sessions suivantes. C’est l’organisateur lui-même Nick Payne de chez Bearpark Publishing qui a présenté DevWeek à un public impatient, avant de passer la main à John Robbins, « Monsieur Debugger » de chez Wintellect, pour une session « Demo Oriented » sur le sujet "Quoi de neuf dans VS 2005 ?" (petite parenthèse : pour ceux qui connaissent physiquement John Robbins, j’ai été impressionné par sa transformation version body-builder).

Dans cette session, John a utilisé tout son art (cet homme aime être sur scène) pour nous impressionner par la multitude des nouveautés de Visual Studio 2005 : côté langage de programmation, côté IDE décliné par langage, puis enfin côté debugging. Si de nombreuses nouveautés ont déjà été présentées dans de nombreux articles, je dois reconnaître que certaines m’étaient inconnues jusque là. Comme par exemple la puissance de l'Intellisence sur les génériques, la gestion des snippet de code contextuel fondée sur des fichiers XML, mais aussi les concepts de refactoring généralisés (insertion : d’un switch/case avec l’énuméré courant, d’un block try/catch, d’une méthode via intellisence avec des paramètres nommés, d’un namespace correspondant à type nouvellement saisi …).

Bref, une session éblouissante même si elle n’était pas vraiment structurée (pas de slide, que des démonstrations). Enfin, notons que cette session n’a pas abordée la partie serveur de Team System.
Vous trouverez les codes sources de cette session sur l’url suivante : http://www.devweek.com/code/robbins-newinvsnet-2005.zip

What’s new in C# 2.0 Part 1 & Part 2

Qui ne connaît pas Jeffrey Richter de chez Wintellect ? C’est « Monsieur CLR » pour de nombreux développeurs .NET. En effet, Jeffrey travaille depuis octobre 1999, comme expert consultant pour Microsoft au sein des équipes CLR. Il connaît donc parfaitement les intentions qui ont poussé Microsoft à faire évoluer le Framework. Dans cette double session Jeffrey nous a présenté respectivement les Génériques, les Méthodes Anonymes, les Itérateurs, les types Nullables et les autres éléments du Framework moins structurants.

Les génériques sont d’après Jeffrey la caractéristique la plus importante du langage C# 2.0. Ils apportent une réutilisation générique sur le plan des algorithmes sans entraîner des effets de bord à la C++ et même à la Java 1.5. En effet, l’équipe CLR a particulièrement travaillé sur cette nouvelle caractéristique syntaxique (plus de box/unbox sur les conteneurs, type safe à l’insertion d’un élément, le code de l’algorithme n’est pas nécessaire, par excroissance du code engendré …). L’essentiel des collections 1.x a été traduit dans le 2.0 de manière à migrer son code en douceur (List<T> : ArrayList, Dictionary<K, V> : Hashtable, SortedDictionary<K, V> : SortedList …). Jeffrey signale que pour renforcer l’usage des génériques dans le C# 2.0, Microsoft a sollicité sa société Wintellect pour concevoir une librairie dans l’esprit de la STL C++ : PowerCollections. Toujours dans le cadre des génériques, Jeffrey a insisté sur les contraintes que le développeur peut appliquer sur sa classe afin d’obtenir un code plus vérifiable (class SortedCollection<T> where T : Comparable {…}).

Sur le sujet des itérateurs, Jeffrey à tenu un discours relativement tranché ; selon lui, ils est préférable de les éviter si les performances sont critiques et quelles que soient leurs formes actuelles (IEnumerable) ou v 2.0 (yield). Selon lui le coût du pattern est trop élevé alors qu’un simple indexer suffit « arr[idx] ». Enfin, Jeffrey propose d’utiliser dans le cadre de v2, la forme générique des conteneurs, qui possède de nouvelles méthodes pour substituer les itérateurs .NET:
- public void ForEach(Action<T>, action);
- public void FindAll(Predicate<T> match);
- public void Sort(Comparison<T> comparison) ;
- public List<U> ConvertAll<U>(Convert<T,U> Converter) ;

Contrairement aux itérateurs v1.x ou v2, ces méthodes offrent des performances acceptables pour Jeffrey Richter.
Sur le plan des méthodes anonymes, il reconnaît le gros travail du compilateur pour apporter une facilité d’écriture aux développeurs (lui compris), mais vis-à-vis des perfs (son grand sujet) les méthodes anonymes n’apportent absolument rien.
Sur la notion de type Nullable, Jeffrey a rappelé l’intention de ce type qui vise essentiellement les bases de données, ainsi que sa syntaxe (étrange) dans le monde C# (par exemple « double? a ; ») puis a détaillé l’implémentation (public struct Nullable<T> & static class Nullable<T>…) d’un point de vue interne.

Sur les éléments moins structurants (types partiels, classe statique, assemblage ami, les directives d’alias sur les espaces de noms …) Jeffrey à nettement moins insisté et je ne les détaillerai pas ici.
En bref, cette double session était particulièrement intéressante, car Jeffrey a présenté la nouvelle caractéristique du compilateur C# v2 sur le thème des performances. Enfin contrairement aux excellents articles de Patrick Smacchia sur la version 2 de C# (génériques, itérateurs, méthodes anonymes, nullables), Richter n’a jamais présenté son exposé sous un angle design pattern mais toujours sur le plan des performances.
Vous trouverez les codes sources de cette session sur l’url suivante : http://www.devweek.com/code/richter-samples2005.zip

.NET development tools

Cette session présentée par John Robbins, traitait des outils (classiques) indispensables pour le développeur .NET 1.x (Visual Studio 2005 n’était pas dans le périmètre de cette session). Côté tests : NUnit, ou mieux encore MbUnit (surensemble puissant à la syntaxe NUnit). Côté documentation : NDoc (avec un warning sur le problème posé par la compilation incrémentale et la génération des commentaires en XML), FxCop (avec une illustration sur la façon d’engendrer des règles personnalisées sur le cas d’une règle boxing/unboxing). Quant au désassemblage / offuscation, il a évoqué Reflector et Wise Owl Demeanor (commercial). Enfin, sur le plan des expressions régulières RadSoft Regular Expression Designer et RegexDesigner .NET.

Cette session sans grandes nouveautés sur le plan technique, était cependant intéressante de par les illustrations concrètes de John Robbins sur chacun des outils.
Vous trouverez les codes sources de cette session sur l’url suivante : http://www.devweek.com/code/robbins-dotnettools-2005.zip

Wintellect “Grand Prix Programming”

Cette séance organisée après un Long Drink, se voulait être une compétition entre tous les speakers de chez Wintellect, présents au DevWeek : Jeffrey Richter, John Robbins, Jeff Prosise et Dino Esposito. L’objectif était pour chacun de présenter un sujet technique en moins de 15 minutes. Deux personnages ont particulièrement marqué le public : John Robbins et la génération d’un mini dump via ADPlus (il n’y a que le nom qui soit « Mini ») et l’exploitation de celui-ci avec WinDbg via son extension « Son Of Strike » (SOS) pour gérer le code managed, et Dino Esposito nommé « Monsieur DataGrid », pour son charme typiquement italien s'est quant à lui penché sur une étude de cas ASP .NET 1.x : comment déplacer des lignes dans DataGrid sans solliciter à chaque déplacement un aller/retour avec le serveur. Notons que ces sessions sont inspirées des articles des speakers respectifs dans le MSDN Magazine du mois de Mars 2005 : BugsLayer & Cutting Edge.

Deuxième journée

Transaction in .NET 2.0

Cette session était animée par Ingo Rammer, l’auteur d’Advanced .NET Remoting chez APress (dont la seconde édition vient de sortir) qui se définit comme un spécialiste des architectures distribuées. Avant d’introduire l’usage de System.Transaction, Ingo a élégamment rappelé la motivation des transactions dans le quotidien d’un développeur. Puis il a décrit tous les moyens disponibles sur la plateforme Microsoft pour jouer des transactions distribuées (COM+, EntrepriseServices, SQL Server compris), pour enfin terminer sur la motivation de cette session : quand et comment utiliser System.Transaction vis-à-vis des gestionnaires de transactions :
- LTM (Ligthweight Tx Manager) utilisé en « inproc » dans un cadre full .NET 2.0
- DTC pour orchestrer des ressources extérieures distribuées
Il a ensuite détaillé le processus de « promotion » d’une transaction avec pour exemple ADO.NET et SQL Server 2005, le DTC et le LTM. Il a enfin insisté sur la capacité d’intégrer nos propres ressources à participer à une transaction en implémentant l’interfaces IEnlistmentNotification.
Finalement, dans cette session, Ingo a peut être passé trop de temps à rappeler les principes de l’architecture transactionnelle actuelle et pas assez sur le sujet de la session, « Transaction in .NET 2.0 ». Malgré cela, Ingo Rammer reste un excellent orateur technique.

Vous trouverez les codes sources et les slides de cette session sur l’url suivante :
http://www.thinktecture.com/conferences/slides/devweek2005/TransactionsInDotNetVersion2.zip

Extending the Visual Studio .NET IDE

Contrairement aux versions précédentes (VC++ 6.0 par exemple), VS .NET propose une architecture extensible permettant d’étendre votre environnement de travail en construisant des outils intégrés qui améliorent votre productivité quotidienne. Dans cette session animée par John Robbins, tous les éléments nécessaires pour construire des Addins compatibles VS .NET ont été démontrés. Pour introduire le sujet, John nous a présenté les capacités d’engendrer des Macros sous VS.NET (sachant que selon lui, la meilleure façon d’apprendre les macros est d’inspecter le code engendré par un enregistrement). Notons que le langage des macros est VB .NET pour ses facultés de « late binding ». Le code VB .NET permet d’appeler des composants .NET, des composants COM, et le modèle objet interne de l’IDE de VS .NET (Dans l’aide MSDN rechercher :
 mshelp://MS.VSCC.2003/MS.MSDNQTR.2004JAN.1033/vsintro7/html/vxgrfAutomationObjectModelChart.htm).

Ce modèle objet orienté racine unique, nommée DTE (Development Tools Extensibility), permet d’accéder aux fenêtres, aux documents, aux projets types .NET, de debugger … A travers ce modèle objet, John a nous explique que nous pouvons éditer via la programmation, le texte contenu dans l’éditeur de l’IDE. Nous pouvons aussi être à l’écoute de nombreux évènements provenant de l’IDE (comme le passage du mode design au mode debug, ou ouverture/sauvegarde d’un document, …). Tous ces évènements sont consommables depuis les macros ou les Addins. En complément aux évènements, John nous présente quelques éléments du modèle objet : CodeModels et CodeElements qui permettent d’accéder aux structures d’un code source comme les attributs, les classes, les délégués, les énumérés, les namespaces … Pour illustrer ses propos, John nous a présenté un exemple concret : la macro Commentator permettant d’ajouter la documentation C# pour toute méthode, propriété et classe n’ayant pas déjà une documentation. Celles marquées avec le mot clef « TODO » apparaissent dans la fenêtre Task de Visual Studio .NET. Cette macro peut fonctionner sur un fichier ou sur toute une solution.

Pour conclure, cette session, John nous a présenté la technologie des Addins qui offrent un contrôle de l’IDE et une intégration graphique dans une fenêtre de type « tool » de VS .NET. Contrairement aux macros qui transportent tout leur code source, les addins sont compilés. Les addins peuvent être écrits dans un langage .NET ou en VC++. En réalité les Addins doivent être des composants COM de type ActiveX respectant un jeu d’interfaces prédéfinis (IDTExtensibility2, IDTCommandTarget). Cependant dans le cas d’un développement .NET, John nous explique qu’un bridge portant le nom VSNetToolHostShim doit être placé entre VS .NET et notre code Addin en .NET. Pour illustrer les Addins, John nous a présenté son exemple d’addin nommé SuperSaver permettant de sauver en tâche de fond les fichiers en cours d’édition.

Enfin, je tenais à rappeler que l’ami Sami avait déjà traité le sujet des Addins dans VS .NET à travers un excellent article sur DNG.
Vous trouverez les codes sources de cette session sur l’url suivante : http://www.devweek.com/code/robbins-extendingvsnet-2005.zip

.NET Debugging Part 1 & Part 2

Dans cette double session présentée par John Robbins, l’essentiel des techniques de mise au point avec Visual Studio .NET 2003 a été abordé. Pour débuter, John a rappelé les pré-requis nécessaires pour débugger confortablement en production (PDB en release dans le package de production, mise en place d’un serveur de symboles des logiciels MS, génération de mini dumps AdPlus et utilisation de WinDbg + SOS).
John a ensuite décliné pour chaque technologie .NET les spécificités de mise au point, en insistant sur le cas ASP.NET qui n’est pas forcément trivial. Puis il a rapidement démontré la suite de debuggers qui arrive sur un poste installé avec VS .NET : CORDBG.EXE (parfait pour comprendre le fonctionnement de .NET), DBGCLR.EXE (parfait et rapide pour une application .NET pure), VS.NET & SQL SEVER (depuis le sp3 de SQL SERVER 2K faire à chaque démarrage « exec sp_sdidebug ‘legacy_on’ ») et enfin le cas de VS.NET et le scripting.

Puis John est passé par une longue explication sur les points d’arrêt dans diverses situations (le cas d’un point d’arrêt conditionnel a largement été détaillé). De nombreuses démonstrations nous ont permis d’apprécier la capacité de VS .NET à gérer des points d’arrêts parfois très avancée. Cependant, il nous a mis en garde dans le cas des points d’arrêts conditionnels :
- La condition est sensible au langage de programmation
- Le code est évalué dans l’application et non dans l’IDE
- L’appel d’une méthode de votre application dans la condition …

En conclusion sur ce sujet : à grand pouvoir, grande responsabilité :-)

Puis nous sommes passé sur le cas de fenêtre de Watch, ce qui nous a permis de (re)découvrir comment étendre ses propres types dans cette fenêtre (répertoire $(VS Install Dir)\Common7\Packages\Debugger\MCEE_CS.DAT pour le cas C#). Par exemple, pour le cas de la classe Thread, afficher la propriété Name automatiquement est sans doute une bonne pratique. Notons que l’évaluation des expressions dans la fenêtre de Watch est extrêmement puissante, mais ne repose pas sur le même moteur que celui proposé dans la fenêtre de paramétrage des points d’arrêts conditionnels. Par exemple un Drag&Drop d’une expression depuis l’éditeur de texte vers une ligne de la fenêtre de Watch.

John est passé au cas de la mise des exceptions (.NET, native). Notons que les exceptions personnalisées applicatives sont intégrables dans VS .NET afin de profiter de l’excellente gestion des points d’arrêt vis-à-vis des exceptions.
Enfin, John a présenté les éléments nécessaires pour une mise au point à distance, en insistant sur fait que le compte de Debug utilisé doit être présent sur la machine distante et dans le groupe Debugger Users). Au passage, John a évoqué la très mauvaise intégration des gestionnaires de configuration au sein de Visual Studio .NET sur le plan des performances (avec une petite exception pour le produit Perforce), au point qu’il est sans doute préférable de désactiver l’intégration de son outil de gestion de configuration.

Vous trouverez les codes sources de cette session sur l’url suivante :
http://www.devweek.com/code/robbins-dotnetdebugging-2005.zip

Troisième et dernière journée

Technical Keynotes: What’s new in SQL Server 2005 for Developers

Cette dernière Journée de conférence débute par un Keynotes dédié à la prochaine version de SQL Server. Le speaker principal de session, Fernando Guerro, est un sympathique spécialiste de SQL Server à la sauce « spanish ». Cette session très macro (mais orientée développement), nous a présenté point par point les grandes nouveautés de SQL Server 2005 :
• Core Engine : Nouvelles instructions TSQL pour les langages DDL et DML, Intégration de la CLR, nouvelle brique de connexion cliente qui remplace le MDAC, XQUERY …
• Data Transformation Services : Nouvelle source de données (document XML), Modèle objet extensible (tâches personnalisées) …
• Analysis Services : Nouvel environnement BI Development Studio, Nouvel algorithme pour le Data Mining, ADOMD.NET (enfin) …
• Full Text Search : Plus efficace (tient compte de la culture), plus de 100 fois plus rapide que la version précédente.
• Replication : Produit des DataSet plus petits. Extrêmement disponible, la Business logique est gérée en .NET …
• Notification Services : Solution extrêmement disponible également, fondée sur XML et TSQL …
• Reporting Services : Interface Web d’administration, VS .NET permet de modéliser les rapports depuis n’importe quel fournisseur de données .NET, Rapports interactifs …
• Native http Support : Expose nativement le service web, n’utilise pas IIS (http.sys), peut servir de front end pour SQL Server
• Service Broker : offre des exécutions asynchrones, n’utilise pas MSMQ (technologie intégrée au moteur SQL, s’exprime via des instructions TSQL).

En conclusion, cette session « panorama » a permis de mieux apprécier l’envergure de l’offre SQL Server 2005. Cependant, à l’heure où le Grid Computing devient un élément clef pour de nombreux clients, on peut s’étonner que Microsoft n’ait pas déjà emboîté le pas de son grand adversaire sur le plan des bases de données, Oracle, qui dans ce domaine, possède déjà plusieurs longueurs d’avance.

.NET performance tips and tricks

Pour John Robbins, le monde des performances se divise en deux : les performances réelles (ce que tout le monde pense lorsque l’on parle de performances) et les performances perçues par l’utilisateur (plus difficiles à définir) mais qui dans de nombreux cas peuvent se traduire pas une amélioration de la disponibilité de l’interface graphique. Pour John, la démarche pour traiter ce type de problème de performances, est d’observer comment l’utilisateur manipule son application vis-à-vis du design proposé. En bref, la perception de lenteur à travers une interface est souvent adressable en offrant plus d’informations sur les traitements en cours tout en lui permettant de faire une opération s’il le souhaite. Les problèmes d’algorithmes correspondent à la majorité des problèmes rencontrés et sont généralement dus à des mauvais designs dans les algorithmes eux-mêmes. Avant de se jeter dans une optimisation systématique du code, il est préférable d’obtenir des métriques historisées sur une période significative, puis prendre des mesures au regard des métriques observés. Puis John a passé en revue les principales techniques pour améliorer les performances : ne jamais calculer quelque chose dans une boucle alors que vous pouviez le calculer hors boucle, vérifier toujours deux fois les lignes contenues dans les boucles. Sur du code .NET, les réflexes de développeur Win32 ne sont pas toujours les bons, de plus la documentation n’est pas toujours complète : le code source de Rotor permet de mieux comprendre le fonctionnement de la plateforme, sinon Reflector permet parfois de mieux comprendre ce qui se cache sous une API qui ne semble pas très performante. Sur le plan de la mémoire, il ne faut jamais appeler GC.Collect (sauf cas particulier).

 Les compteurs de performances permettent d’observer (PerfMon.exe) de nombreuses métriques concernant la gestion mémoire .NET. Pour visualiser la mémoire consommée, il existe de nombreux produits, sachant que le « CLR Profiler » fournit avec VS .NET, permet déjà d’en apprendre beaucoup sur la consommation mémoire d’une application pas trop grosse. Sinon des produits commerciaux offre des services similaires même plus conviviaux et plus rapides que le « CLR Profiler ». Sur le plan de la Finalisation .NET, vérifier que seuls les objets agrégants des ressources natives possèdent une méthode finalize() (où un destructeur en C#). Et enfin, vérifier que le pattern Dispose est bien appliqué. Sur la plan du Boxing / Unboxing (mangeur de performances), vérifier que le code (IL) n’en abuse pas. Par exemple John fournit une règle personnalisée à FxCop permettant de vérifier ce problème.

Vous trouverez les codes sources de cette session sur l’url suivante : http://www.devweek.com/code/robbins-performancetips-2005.zip

The art of thread synchronization

Avec un titre aussi alléchant et en plus animé par le grand Jeffrey Richter, je ne pouvais manquer cette session dédiée aux bonnes pratiques de synchronisation de threads au sein de la plateforme .NET. Cette session a débutée par un panorama des performances de classes dédiées à la synchronisation inter-threads. Puis, Jeffrey à présenté une implémentation personnelle d’une classe de synchronisation (Simple Optex Lock) tirant le meilleur (à la fois sur le plan des performances et l’usage) des classes fournies en standard.

Puis Jeffrey a rappelé que contrairement aux APIs Windows de synchronisation qui conservent l’ordre des threads en attentes (FIFO), les classes de synchronisation .NET ne conservent pas cet ordre, car lorsque le Garbage collecte, celui-ci suspend tous les threads de l’application, puis lorsque celui-ci a terminé ses opérations de nettoyage, il relance les threads qui se répartissent sur les ressources dans un ordre différent à l’état précèdent la collecte (phénomène de « race condition »). Dans ce cadre, il est donc possible (mais sans doute rare) qu’un thread n’obtienne jamais l’accès à une ressource désirée. Selon Jeffrey, si votre application impose un ordre dans les traitements basés sur des threads : « N’utilisez pas .NET ».
Puis Jeffrey à traité le cas des verrous lecteurs / écrivains, illustré par la classe ReadWriteRessourceLock qui selon lui comporte principalement des problèmes de performances.

La session s’est terminée par un exposé détaillé sur un verrou dédié aux architectures SOA (SoaReadWriteLock) développées par Jeffrey lui-même. Pour la petite histoire, Jeffrey serait en attente d’un retour de Microsoft pour lui payer des droits d’utilisation de son verrou au sein du Framework. Il faut dire que son verrou orienté lecteurs / écrivains, n’impose aucune condition particulière sur le plan système et offre donc des performances excellentes (le code source de ce « super » verrou est fourni dans les sources !
Vous trouverez les codes sources de cette session sur l’url suivante : http://www.devweek.com/code/richter-samples2005.zip

Building management apps with WMI 

Cette session était aminée par le sympathique Dominick Baier, spécialiste de la sécurité chez DevelopMentor UK, qui a traité cette session avec pragmatisme car il faut bien le reconnaître l’intégration de .NET au sein de WMI reste fort incomplète. Cependant, Dominick a parfaitement présenté WMI, tant sur les motivations (par exemple appliquer une politique de monitoring si un même utilisateur échoue 3 fois successivement pour se loger) que sur l’implémentation Microsoft en terme de modélisation (MOF : proche d’un IDL COM), d’outils et de technologies (principalement non .NET mais COM). Notons que par défaut VS .NET 2003 (contrairement à VS 2005) ne fournit pas l’extension « Management (WMI) Extensions for Visual Studio .NET 2003 Server Explorer ». Cependant vous pouvez la télécharger ici. Bref, un juste équilibre entre la pratique et les démonstrations ; on regrette simplement que la version 2.0 du Framework .NET ne comble pas le manque des fonctionnalités présentent dans les versions 1.x.
Vous trouverez les codes sources de cette session sur l’url suivante :
http://www.leastprivilege.com/PermaLink.aspx?guid=73d279ec-5502-4fce-ba48-64fec69916a2

Conclusion

DevWeek 2005 a brillé par la qualité de ses présentateurs, mais a sans doute déçu par son organisation un peu (trop) rustique. Effet, l’organisation générale était parfois artisanale, comme l’affichage des sessions pour signaler les salles retenues, réalisé sur des feuilles volantes ou le manque de micros dans les salles (pour poser des questions). De même il n’y avait pas d’accès systématiques aux versions électroniques des slides (le format papier était de six diapositives par pages, donc souvent trop petit), pas d’accès web pour les participants… Bref une conférence à petit budget, mais qui reste malgré tout une excellente conférence à taille humaine, comparativement aux Blocks Busters américain (TechEd , VSLive).


Site Officiel de DevWeek
: http://www.devweek.com