dimanche 31 janvier 2010

Quelques lectures en prévision

J'ai récemment reçu quelques chèques livre de Jyce que je remercie chaleureusement au passage.
Ce week-end, je me suis donc rendu dans ma librairie préférée pour les convertir en papier à grignoter :-)
Dans un premier temps, je voulais remettre la main sur un excellent dictionnaire des créatures légendaires, mythiques et fantastiques (peut-être celui-ci ou celui-là).
Malheureusement, il ne s'y trouve plus! Il me faudra retrouver la référence de l'ouvrage :-|

Je n'ai rien perdu au change car ma librairie regorge d'excellents ouvrages.
A défaut de mon dictionnaire (ce sera pour une prochaine fois), je suis ressorti avec des ouvrages qui me feront passer d'agréables moments:
Voila, avec cela, ma liste de lecture passe à 42 ouvrages.

jeudi 28 janvier 2010

Créer le script "Create Table" d'une table

Introduction
Il est quelque-fois nécessaire de déplacer ou dupliquer recréer plusieurs tables d'une DB à l'autre.

La technique la plus simple consiste en obtenir le script sql de création (Create Table) et de l'appliquer sur l'autre base de donnée.
Cette opération peut être effectuée manuellement ou automatiquement.

Option manuelle
Cette option est idéale lorsque l'opération doit être exécutée une seule fois et sur un nombre restreint de table (object).
A cette fin, l'on utilise les fonctionnalités du "Sql Management Studio" pour recréer ce script.
Ce procédé largement répandu est décris sur d'autres articles tel que "SQL SERVER – 2005 – Create Script to Copy Database Schema and All The Objects – Stored Procedure, Functions, Triggers, Tables, Views, Constraints and All Other Database Objects" publié sur Sql Authority.

Si cette solution est intéressante au cas par cas, elle à l'énorme inconvénient de nécessiter l'intervention humaine.

Option automatique
L'option automatique (à l'aide de code exécutable comme des stored procedure) à l'avantage de répéter une opération de façon systématique. C'est encore plus avantageux si la tâche est répétitive.
Bien qu'ayant déjà fureté un peu sur le net, il n'existe pas de "stored procedure" ou "extended procedure" permettant d'obtenir un tel script depuis Sql Server lui-même.
Pour le moment, seul SMO semble offrir une alternative intéressante.

Getting CREATE SCRIPT with SMO
Une solution possible pour obtenir le script de création d'un objet (table) est d'écrire un bout de code en VB ou .Net qui utilise l'API SMO (Sqlserver Management Object) pour obtenir les script en question.
Pour rappel, SMO est également l'API utilisée par "Sql Server Management Studio".


La discussion de cet article "Dynamic Stored Proc to generate Create Table Script ,taking table_name as parameter" fournit déjà un bout de code à partir duquel il est possible d'élaborer une solution.
SQL DBA Tip publie également l'article "Getting Started with SMO in SQL 2005" (avec code de démonstration).

Programmer le port parallèle et touch devices avec .Net

Programmation du port parallèle en .Net
En guise de détente, voici deux articles qui expliquent comment contrôler l'état du port parallèle de votre PC.
Pour les bricoleurs et les débrouillards, voici quelques images des l'articles publiés sur "The Code Project".





Devices tactiles en .Net
Dans la même veine des articles un peu différent, voici un article qui s'attarde sur la capture tactile en .Net.
Encore une fois un article "The Code Project". 

mercredi 27 janvier 2010

Documentation C# - C#3, C#4, Tutoriel techniques, mem leaks, Trace et Debug

Voici une série d'articles dignes d'intérêts...

Eviter les memory & ressource leaks en .Net
Contrairement à ce que beaucoup de développeurs pourraient penser, la mise en place d'un "Garbage Collector" dans le FrameWork .Net ne met pas le développeur à l'abri du memory (& ressource) leak.
L'article "How to detect and avoid memory and resources leaks in .NET applications" parut sur MSDN nous explique qu'il existe toujours des cas et situations où les memory leaks (et/ou ressources leaks) sont possibles.
Il montre également comment les détecter et les éviter.

Debug &  Trace
Excellent article que "CodeProject A Treatise on Using Debug and Trace classes, including Exception Handling. Free source code and programming help".
Il explique pourquoi il faut utiliser Trace.Assert & Debug.WriteLine!
Il montre également comment implémenter un "Custom Debug Class" pour obtenir des fonctionnalités précises et en Debug et en Release (histoire de facilité la vie des développeurs).
Finalement, il montre comment implémenter un "ExceptionHandler" (InitializeUnhandledExceptionHandler, DbgExceptionHandler) pour capturer les exceptions remontant jusqu'au framework (afficher des messages d'erreurs plus professionnel).

Tutoriels Technique .Net
Elise dupont publie une série de tutoriel sur www.dotnet-tech.com depuis 2003.
Voici une liste des documents PDF (aux noms déjà évocateurs) disponibles depuis la page principale.
Application-blocks
Asp_net_2_securite
AspNet_Excel_2
Assemblies
Config&Custom_asp
Controle_wysiwyg_part1, 2 et 3
Intro_remoting
ldap
localisation
Office&WebServices
premiers_controls_web
procstock&VS.net (gestion de stored procedure avec VSS)
RepportsExcel_Asp.net
rss
Security_partie1 et 2
Securitedotnettech
serialisation
serialisation_complexe
service_windows
TransparenceModeUnsafe
webparts
Windows XP 1
wsattach

Nouveauté C#3
Quelques articles concernant les nouveautés C#3 (disponibles sur Developer.com).
Nouveauté C#4
Pour le moment, il n'y a qu'une entrée... mais cela va certainement se combler très vite.

lundi 25 janvier 2010

Dix outils que tous les developpeurs .Net devraient avoir

En juillet 2004, MSDN Magazine à publié l'excellent article "Ten Must-Have .NET Tools Every Developer Should Download Now" de James Avery.

Cet article est un excellent point de départ pour découvrir quelques outils très utiles pour l'environnement .Net.
En voici quelques-uns...

Snippet Compiler
C'est une petite application qui permet d'écrire et compiler rapidement des petits bouts de code .Net.
Plus besoin de démarrer Visual Studio et de commencer un nouveau projet pour faire quelques tests ou écrire un petit bout de code "démo"
Snippet Compiler sait se montrer terriblement efficace.
Parmi les éléments non mentionner dans l'article, il est possible d'ajouter des références au snippet en cours d'écriture. Bien pratique pour tester et mettre à mal un assembly fraîchement livré :-) .
Info sur Snippet Compiler.

Regulator et Regulazy
Régulator est un outil pour écrire et tester facilement des expressions régulière (wikipedia, Learn - Test regular expression with regulator).
L'initiateur du projet regulator à également initié Regulazy, un outil permettant d'écrire plus facilement des expressions régulières à partir de vos propres exemples.
De vrais petits bijoux pour les développeurs.
Plus d'information ici.

.Net Reflector
Outil red-gate qui utilise la réflexion pour analyser, décompiler et explorer les classes & méthodes d'un assembly.
Un incontournable pour les développeurs .Net.
Plus d'information sur la page d'accueil de Reflector.

NUnit
Outil permettant de d'écrire et automatiser des sessions de Unit Testing (wikipedia).
L'article "Test-Driven C#: Improve the Design and Flexibility of Your Project with Extreme Programming Techniques" de MSDN Magazine aborde d'ailleurs ce sujet. 
Voir le site officiel pour plus d'information.
A noter que l'environnement Visual Studio dispose d'un plug-ins developpé sur SourceForge.

NDoc
Il est possible, en C#, de rapidement et facilement documenter son code (methodes, arguments, classes, etc) à l'aide des balise xml summary (///).
A la compilation, ces informations peuvent être utilisées pour générer des fichiers Xml contenant la documentation du code.
NDoc récupère ces fichiers mais utilise également la réflexion sur les assembly pour (re)constituer une document précise.
La force de NDoc réside principale dans les formats de documentation qu'il est capable de produire (Html, Chm, etc). 
Plus d'information à propos de NDoc sur SourceForge.

samedi 23 janvier 2010

Les livres lus en 2009

Livres lus :


  • 15 ans après de Alexandre Jardin du 08 décembre au 02 janvier 2010 
  • Fanfan de Alexandre Jardin du 30 novembre au 07 décembre 2009
  • Le prédicateur de Camilla Lackberg du 12 novembre au 29 novembre 2009  
  • Das System de Karl Olsberg du 6 novembre au 11 novembre 2009  
  • La promesse des Ténèbres de Maxime Chattam du 25 octobre au 6 novembre 2009 
  • La conspiration du temple de Steve Berry du 13 septembre au 24 octobre 2009
  • Tintin-King Ottokar's Sceptre de Hergé du 29 Aout 2009 au 27 septembre 2009
  • Théatre (volume1) de E.E. Schmitt du 16 Août 2009 au 28 Août 2009 
  • Troie (volume 1) de David Gemmell du 21 juillet 2009 au 18 Août 2009
  • L'énigme Alexandrie de Steve Berry du 26 mai 2009 au 19 juillet 2009
  • Meurtre.com de Jeffery Deaver du 06 mai 2009 au 25 mai 2009 
  • Autre Monde (vol 1) - L'alliance des trois de Maxime Chattam du 25 avril au 05 mai 2009
  • La Proie de Michael Crichton du 13 avril au 24 avril 2009
  • Les manipulateurs sont parmis nous de Isabelle Nazarre-Aga du 23 mars au 12 avril 2009
  • BD - Calvin & Hobbes - integral vol 2 de Bill Watterson 27 mars 2009 ??
  • Petits crimes conjugaux de Eric Emmanuel Schmitt du 17 mars au 22 mars 2009
  • L'héritage des Templiers de Steve Berry du 10 février au 16 mars 2009
  • BD - Tintin & the land of black gold de Hergé 07 février 2009
  • BD - Calvin & Hobbes - integral vol 1 de Bill Watterson 27 janvier 2009
  • Les pommes d'Or du Soleil (nouvelles) de Ray Bradbury du 08 janvier au 01 février 2009
  • Millénium 3 - La reine dans le palais des courants d'air de Stieg Larsson du 14 décembre 2008 au 07 janvier 2009

jeudi 21 janvier 2010

Support des Sets et test d'inclusion en C#

Au cours d'une séance d'exploration sur la classe XmlReader en C#, je suis arrivé à un point où il me fallait écrire un traitement conditionnel dépendant du type de noeud xml (XmlReader.NodeType).

Dans un tout premier temps, j'ai voulu tester si le type de noeud en cours de lecture était une entité Element ou CData.
Cependant, je m'attendais également à devoir rallonger la liste des éléments à supporter dans mon test.
Je me suis donc attardé sur les test d'inclusion.

Coding standard en C#
Le test d'inclusion pouvait s'écrire:
if ((myReader.NodeType == XmlNodeType.Element) || (myReader.NodeType ==XmlNodeType.CDATA) )
doTraitement1();
else
doTraitement2();
Cependant, cette option (tout comme le switch) aura le désavantage de dégrader la lisibilité s'il faut étendre le test pour supporter de nouvelles valeurs.

Coding en Delphi
Delphi (tout comme Sql ou Python) supporte la notion d'ensemble (les Sets).
Delphi offre par ailleurs la possibilité d'effectuer des tests d'inclusion sur un paramètre à l'aide de ces ensembles.
C'est ainsi que le test d'inclusion suivant est tout à fait valable en Delphi.
if FieldType in [DataType_Numeric, DataType_Text] then 
doTraitement1()
else
doTraitement2() 

Une approche LinQ en C#
Je n'ai malheureusement pas encore trouvé d'écriture similaire à celle de Delphi pour C#.
Cependant, LinQ et les generics offrent la possibilité d'écrire des tests d'inclusion.
Le but étant de construire une collection contenant les valeurs admises et de vérifier si cette collection contient le paramètre à tester.
L'exemple ci-dessous démontre ce principe.
...
XmlTextReader myReader = new XmlTextReader(myFile);

if (
   (new List<XmlNodeType>(){ XmlNodeType.Element, XmlNodeType.CDATA }).Contains( myReader.NodeType ) )
  Console.WriteLine("myReader.ReadContentAsString = " + myReader.ReadContentAsString() );

Ajouter le support des Set à C#
Parmi tous les dérivés des collections, C# (jusqu'à la version 3.5 du Framework) ne dispose pas de structure de type Set.
Un set dispose des fonctionnalités suivantes:
  • Un set contient une liste d'élément (chaque élément étant présent une seule fois).
  • Le traitement des Set est rapide.
  • Les Set disposent d'opération d'inclusion, union, intersection, de test, etc.
  • Les Set disposent d'opérateurs permettant un codage clair et efficace.
Si C# manque cruellement de Set, l'article "Add Support for "Set" Collections to .NET" sur "The Code Project" essaye de résoudre ce problème avec un certain brio.
A côté des développement sur "The Code Project", il existe également la collection de classe C5.

Support des Set pour .Net 3.5
En information de dernière minute, il semblerait qu'il existerait une classe HashSet() à partir de la version 3.5 du framework
Je vais me pencher un peu la dessus...

Quelques exemples en C#


Maintenant que je suis prêt à me re-jeter corps et âme dans l'environnement .Net, j'ai installer Visual Studio C# 2008 Express sur mon PC.
C'est ainsi que j'ai eu le bonheur de retrouver quelques vieux exemples datant de Juin 2008 (ça date l'air de rien).
A l'époque, j'explorais la plateforme .Net et essayais de trouver les notions .Net correspondantes à certains concepts Delphi.
 
26/12/2009, Aujourd'hui, ces exemples sont un excellent point de départ pour me replonger dans le bain.
06/01/2010, Ajouté quelques exemples concernant les IEnumerable, les collections, Linq, Lamba expression, etc
17/01/2010, Ajouté des exemples sur les types anonymes, l'extraction d'ExeName, Manipulation de nom de fichier, et surtout quelques exemples XML
21/01/2010, Ajouté des exemples sur XmlReader, compression de stream (& string), encryption AES.

Voici une petite liste récapitulative des éléments explorés:
Basic Demo
  F1: detecting F1 key-press
  1 : test delegate
  2 : using 'ref' keyword
  3 : returning an newly created object
  4 : Constructor Parameters
  5 : Singleton (using abstract)
  6 : FileWriter and IDisposable interface
  7 : Property
  8 : Enumeration (and Flagged Enumeration)
  9 : Raise Exception
  a : Abstract
  b : Interface Demo (and enumeration)
  c : Struct
  d : Arrays
        - array of int
        - array of objects (inheritance, base call)
        - Multidimensionnal array.
        - Strairs/cascading array.
        - Array toolbox (for string handling)
            *
        - Sorting array of object
  f : Yield Return & IEnumerable
  g : Debugging
        - Assertion via System.Diagnostic.Debug.Assert()
        - OutputDebugString (Debug.WriteLine)
        - Tracing via System.Diagnostic.Trace.WriteLine()
  h : Collections
        - Indexer (Access class as an Array)
        - Implement IEnumerable to use the "foreach" on the class.
        - List<T> (AddRange, Exits, Any)
        - List<T> (LINQ, IEnumerable, ToList, ToArray, String.Join)
        - Queue<T> (LinQ, ToList, ForEach and LAMBDA expression)
        - Stack<T> (populate from LinkQ + Lambda,
                    populate from IEnurable + foreach
                    Create from IEnumerable )
        - InspectEnumerator: Display content of a IEnumerable<String>
                    (via the IEnumerator<String> GetEnumerator() )
  i : Anonymous type
        - Create complex structure
        - Array of anonymous type
        - List of anonymous type!!!
  j : ExeName
        - with executing security consideration
        - ASSEMBLY.GetExecutingModule()
        - Path.xxx (decomposing filename)

XmlDemoApp
    1: Create & Display an XmlDocument
            - initializer member (very nice)
            - XmlDocument, CreateElement, CreateAttribute, CreateCDataSection
                CreateXmlDeclaration
            - Save & Load (NOT USING stream & XmlReader/WmlWriter)
            - XPath (selectSingleNode, selectNodes)

    2 : XSL transformation
            - XmlNavigator, XslCompiledTransform
            - File.Exists, File.Delete
            - FileStream

    3 : XML Reader
            - XmlTextReader
            - USING keyword
            - Test a XmlNodeType value against a list of possible values List<T>
            - MoveToNextAttribute

MiscDemoApp 
    1: Compress/Uncompress String
            - Encoding.UTF8 (convert string to UTF-8 byte[] buffer)
            - GZipStream and MemoryStream
            - System.Buffer handling (BlockCopy)
            - BitConverter
            - Convert.ToBase64String

    2 : Compress and Transport Thousands of struct.
            - Interesting et very fast method based on Buffer Copy

    3 : AES Encryption
            - Create the AesHelper class
                    Using Crypto Stream & buffer
            - Encrypt & Decrypt String
            - Wrong passPhrase would cause exception

Télécharger le code source des exemples.

Sql Server 2005: Logger les messages et résultats de script sql dans un fichier

Introduction
Nous avons de longs scripts de migrations et ces derniers produisent de nombreux messages (jusqu'a 15 millions de lignes).
Pour des raisons de validation, cette information doit être tenue en rétention pendant une période plus ou moins longue.
Dans cette quantité incroyable d'information (dont certains "x rows affected" ne peuvent être évités), il convient également de pouvoir faire des recherches sur des mots clés (comme par exemple "error").

C'est que la manipulation de logs/résultats aussi longs n'est pas franchement dans les cordes du Management Studio de Sql Server.
Certains logiciels en ligne de commande s'en sortent vraiment mieux.

Le besoin
Il faut donc avoir la possibilité d'exécuter des scripts sql et récupérer les messages (et si possible les résultats) dans un fichier texte.
Ce fichier pourra par la suite être utilisé pour effectuer les vérifications nécessaires.

La solution: SqlCmd
SqlCmd est un utilitaire Sql Serveur en ligne de commande.
Apparu avec Sql Server 2005, ce dernier permet d'exécuter des scripts (en intéractif ou non) depuis une console DOS. Très pratique pour automatiser certaines tâche (ou accéder à la connexion administrative), SqlCmd permet également d'exécuter des fichier Sql et récupérer les résultat et ce y compris les messages.

Voici, en guise d'exemple, le fichier batch "Exec.bat".
Il exécutera les scripts sql contenu dans le fichier "MessageToFile.sql" (voir plus bas) à l'aide de SqlCmd.
Les résultats d'exécution sont eux stockés dans le fichier d'output "result.txt":
Cet exemple démontre:
  1. Que les datasets SQL sont écrits dans le fichier output.
  2. Que les messages sont écrits dans le fichier output.
  3. Que les erreurs sont également écrites dans le fichier output :-)
Exec.bat
sqlcmd -U SqlUser -P SqlPassword -S SqlServer -d myDatabase -i MessageToFile.Sql -o result.txt 
Voici une description sommaire des paramètres (attention: il sont case-sensitive).
  • S: Le serveur Sql à contacter. 
  • U: Le login Sql Server utilisé par SqlCmd. Notez qu'il est possible d'utiliser une "trusted connection" à la place. 
  • P: Le mot de passe correspondant au login sql. 
  • d: La base données sur laquelle le script Sql sera exécuté. 
  • i: Input file, le fichier sql à exécuté. Dans le cas ci-present, ke fichier MessageToFile.Sql se trouve dans le même répertoire que Exec.bat. 
  • o: Le fichier d'output dans lequel les messages et résultats seront écrits (dans ce cas, rien n'est affiché à l'écran).

MessageToFile.sql
Ce fichier contient les commandes exécutés par Sql Cmd (via le batch Exec.bat)
-- Output a message
print "Today We are "+Cast( GetDate() as Varchar(30) )
go
-- Output a result
select top 10 name from sysobjects where name like "DF%A%"
go
-- Output having a convertion error
--    Prooving that error are also written to output file
select top 10 Cast( Name as Int ) from sysobjects where name like "DF%A%"
go
-- Output the final message 
--    Proving that even with the covertion error, this messahe
--    is still logged to the file.
print "--- END OF TEST ----"


Result.txt
Le contenu de "result.txt" demontre bien l'écriture (log) des messages, datasets et erreurs sql.
Today We are Jan 21 2010 11:42AM
name                                                                                                                            
--------------------------------------------------------------------------------------------------------------------------------
DF__tblTMProj__Chdat__005FFE8A                                                                                                  
DF__tblLSSign__Chdat__027D5126                                                                                                  
DF__tblDMNumI__ChUse__03A67F89                                                                                                  
DF__tblDMNumI__Chdat__049AA3C2                                                                                                  
DF__tblDSDocu__ChUse__0524B3A7                                                                                                  
DF__tblDSDocu__Chdat__0618D7E0                                                                                                  
DF__dtpropert__versi__0697FACD                                                                                                  
DF__tblRDArm__ChUser__07420643                                                                                                  
DF__tblRDArm__Chdate__08362A7C                                                                                                  
DF__tblDMIFCA__ChUse__095F58DF                                                                                                  

(10 rows affected)
Msg 245, Level 16, State 1, Server myDatabase, Line 3
Conversion failed when converting the nvarchar value 'DF__tblTMProj__Chdat__005FFE8A' to data type int.
--- END OF TEST ----

lundi 18 janvier 2010

Une trouvaille archéologique

Au détour d'un click, je suis retombé sur mon premier site entièrement fait main et maintenu sur les 50 Mb offert par Belgacom.
A cette époque, il fallait en savoir des choses (ftp, html, css, javascript... un peu d'xml et xsl aussi).
C'était une période laborieuse et fastidieuse... à une année lumière (au moins) de la simplicité de Blogger :-)
Soyez patient si vous le visitez, la bande passante des sites perso chez Belgacom laisse franchement à désirer.

jeudi 14 janvier 2010

Microsoft/Web la plateforme "LAMP" pour Windows

Qu'est qu'une plateforme LAMP?
LAMP est l'acronyme de Linux Apache MySql Php.
En gros, avec quelques setups d'installations (ou un guide d'installation), vous installez et configurez une plateforme Linux avec un serveur web, un gestionnaire de base de donnée et un langage de programmation orienté web (PHP).
Il est même possible de trouver des "setup d'installation unique" faisant toutes ces opérations en une fois (ou presque).
Il est maintenant fréquent de dénicher des appliances (machine virtuelle préconfigurée) fonctionnelles en quelques cliques.
Le monde du libre regorge de projet open-source permettant d'installer facilement les applications Web les plus diverses.
En gros, en quelques-click, il devient possible d'installer un environnement et ses applications ouvertes sur le Web. A bien y penser, c'est assez fortiche.

Et Microsoft dans tout cela?
JA la traine dans ce domaine depuis des années, Microsoft s'est finalement réveillé.
C'est ainsi qu'avec Microsoft/Web, la société de Redmon propose également un installation de type LAMP mais avec les produits de Microsoft (bien entendu).
La "Plateforme Web de Microsoft" donne accès au Framework (.Net), au Web Server, au moteur de base de donnée (Sql Serveur) et outils (Suite "Expression") pour construire et mettre en ligne des sites web et applications. Le tout bien entendu, avec un seul logiciel d'installation.
En grattant un peu, le site Microsoft/Web propose également d'installer des version préconfigurées de Joomla, DotNetNuke,Gallery, mojoPortal, ScrewTurn Wiki, WordPress, Drupal, etc pour sa plateforme (voir ici pour les détails).

Loin d'être stupide et n'ignorant pas le succès de PHP, la plateforme WEB de Microsoft supporte également PHP. Plus besoins donc de plusieurs serveurs pour faire cohabiter .Net et PHP :-)

Les outils de développements
La plateforme web est accompagnée d'une série d'outils de développement (page de présentation ici)
On y retrouve:
  • La suite Visual Studio édition Web Developper Express. Plus d'information ici.
  • Microsoft Expression Web 3 Edition Trial pour facilité le design et l'édition de page PHP. Plus d'information ici.
  • Internet Explorer 8 incluant les développer tools (Javascript debugger & profiler, HTML inspector, CSS Tracing). Plus d'information ici.
Besoin de plus d'information:
Je vous invite à visiter Microsoft/Web pour plus d'information.

Merci Jean-Yves pour ce lien super intéressant.

mardi 12 janvier 2010

Initialiser une structure complexe en C# - petite étude sur la lisibilité de code - partie III

Introduction
Suite des articles

Pour rappel, le but de cette série d'articles est de pouvoir initialiser une structure complexes en utilisant un code C# facile à lire et à maintenir. Quelque-chose de similaire (dans l'écriture) aux possibilités offertes par Python.
Bien qu'il soit préférable de lire les deux précédents articles, cela n'est pas nécessaire à la compréhension du code C# repris ci-dessous.

Les types anonymes
Petite définition du type anonyme
Les types anonymes n'ont pas de nom. Pour facilité la compréhension, le mot "type" peut-être remplacé par "classe".
Donc, il est possible de créer des instances de classe sans que cette dernière ait été explicitement décrite.
Les classes anonymes sont cependant beaucoup plus limitées que les classes habituelles.
Elles dérivent immédiatement de "object" et ne dispose que de membres.
A chaque field (champ) accessible dans une classe anonyme correspond une variable privée publiée par une auto-property.

Lors de l'utilisation de type anonymes, le mot clé "new" est utilisé sans spécifier le type de l'objet.
A la place, un property initializer {} est utilisé pour définir et initialiser la structure.

L'objet ainsi crée est stocké dans une référence à l'aide du mot clé "var", ce dernier permettant de bénéficier du typage implicite.

Les types anonymes produisent des classes et que les instances sont des objets, il est donc possible d'appliquer toutes les techniques applicables aux objets (stockage en array, reflexion, etc).

Exemple de type anonyme

var anAlbum = new { Name = "L'as du lavabo", Seconds = 187 };
Console.WriteLine( "name: {0}", anAlbum.Name );
Console.WriteLine( "Time: {0}", anAlbum.Seconds );

// Declaring an CD album as Anonymous type.
// Notice: 
//   1) The usage of var for Implicit Type  
//   2) The class type in not mentionned after the "new"
var CDAlbum = new
{
    Name = "This is it",
    Artist = "Jackson",
    Type = "Pop",
    Year = 2009,
    Info = "1/2",
    // Tracks are declared and stored within an array of anonymous type.
    // The class type is still not mentionned after the "new" and before the "[]"
    //   (array declaration)
    Tracks = new[] {
        // Each track is declared as an anonymous object
        new { Name = "Wonna Be startin' Somethin'", Seconds = 124 },
        new { Name = "Jam", Seconds = 341 },
        new { Name = "Human Nature", Seconds = 243 }
    }
};

Quatrième essai: Les types anomnymes
En utilisant les types anonymes (décrits ci-avant), il est possible de créer ma structure stockant la collection de CD (voir introduction de la partie I) sans alourdir le code avec des définitions de classes qui sont, dans ce cas, inutiles.
De surcroît, l'écrire est très compacte, lisible et aussi efficace que le script Python équivalent.

// Declaring my CD collection with anonymous type structure.
var CDs = new[] {
    // CD 1
    new { Name = "This is it", Artist = "Jackson", Type = "Pop", Year = 2009, Info = "1/2",
          Tracks = new[] { new { Name = "Wonna Be startin' Somethin'", Seconds = 124 },
                           new { Name = "Jam", Seconds = 341 },
                           new { Name = "Human Nature", Seconds = 243 } }
        },
    // CD 2
    new { Name = "Friends", Artist = "Tam-Tam", Type = "Capella", Year = 2007, Info = "Demo disc",
          Tracks = new[] { new { Name = "Sophie", Seconds = 248 },
                           new { Name = "Friends", Seconds = 178 },
                           new { Name = "Le dictionnaire", Seconds = 86 },
                           new { Name = "L'as du lavabo", Seconds = 187 } }
        },
    // CD 3
    new { Name = "History", Artist = "Jackson", Type = "Pop", Year = 2009, Info = "Continues, 2/2",
          Tracks = new[] { new { Name="Scream (duet with Janet Jackson)", Seconds=114},
                           new { Name="They don't care about us", Seconds=108 },
                           new { Name="Smile", Seconds=98},
                           new { Name="Money", Seconds=95} }
        }
};

// Display the result
foreach (var aCD in CDs) {
    Console.WriteLine("Name: {3}, Artist: {0}, Type: {1}, Year: {2}, Info: {4}",
                    aCD.Artist, aCD.Type, aCD.Year, aCD.Name, aCD.Info);

    String _Tracks;
    _Tracks = String.Join( "\n\t\t", 
               (from cdtrack
                in aCD.Tracks
                select "TrackName: " + cdtrack.Name + ", seconds:" + cdtrack.Seconds.ToString()
               ).ToArray<String>() );
    Console.WriteLine("\t\t" + _Tracks );
}

Références:

Windows Azure - Le cloud computing façon Microsoft

En réponse à Google AppEngine, Microsoft lance "Windows Azure" (WAZ) sa plateforme et son service de Cloud Computing.
Très intéressant sur le principe, une telle platforme permet de prendre en charge une application sur le Net.
Les divers services (stockage, exécution, load balancing, gestion de montée en charge, DNS, high availability, etc) étant assuré par les WebFarms de Microsoft.

Probablement bâti sur le Framework .Net, Windows Presentation Foundation (WPF) + Silverlight et Windows Communication Foundation (WCF) , le developpement et déploiement d'application Windows Azure doit, plus que certainement, être relativement simple.

Voici une vidéo de présentation disponible sur Channel9 expliquant ce qu'est Windows Azure.
Cet autre vidéo de Channel9 se concentre sur les solutions de stockages de Windows Azure (d'autres vidéos relatives au stockage sont également disponibles depuis cette page).

Plus d'informations, ressources (sdk, vidéo, training, enregistrement) sur le site d'information de microsoft dédié à Windows Azure.

Stockage d'information
Bien que la plateforme "Windows Azure" propose des tables pour stocker des informations, ces dernières ne tienne absolument pas la comparaison avec les tables de base de données.
Le stockage d'information dans ces tables est plutôt comparable à une feuille Excel.
L'usage des tables est peu contraignant... tout est possible, de l'inconsistance de l'information (car pas de définition de schéma) au formatage totalement libre de l'information.
Il n'empêche que les tables permettront un stockage aisé d'informations élémentaires. Le contrôle du schéma et de l'aspect relationnel devra être pris en charge par la couche applicative.
Cet article "How Do I: Store Data in Windows Azure Tables" montre comment coder eune classe .Net utilisant les tables de Windows Azure pour stocker des informations mais également la configuration des services.

A noter que le service de stockage s'article autour:
  • Des tables
  • Des Blobs (large binary objects)
  • Des Queues de traitement.

Sql Azure
Pour le développement de plus grande envergure, un système de gestion et stockage de données relationnelles doit être envisagé.
Pour répondre à ce besoin, Microsoft propose le produit Sql Azure.
SQL Azure propse des services SQL standard, support TSql, est également Fault Tolerant (tout comme Windows Azure) et prévu pour les sénarios High Availability (car l'information est dupliquée).

lundi 11 janvier 2010

Initialiser une structure complexe en C# - petite étude sur la lisibilité de code - partie II

Introduction
Suite de l'article "Initialiser une structure complexe en C# - petite étude sur la lisibilité de code - partie I".

Pour rappel, le but de cette série est de pouvoir initialiser une structure complexes en utilisant un code C# facile à lire et à maintenir. Quelque-chose de similaire (dans l'écriture) aux possibilités offertes par Python.
Pour pouvoir suivre cet article il est conseillé de lire la première partie qui contient le code C# de départ.

Deuxième Jet
Afin de rendre l'écriture de l'initialisation un peu plus fluide, il serait idéal de déclarer les propriétés du CD avant les propriétés des tracks.
Bien que l'idée ne me plaise pas au premier abord (1), j'ai modifier la propriété Tracks de la classe CD afin d'autoriser le remplacement de la collection via un "setter".

(1) Remplacement d'une référence de collection interne via une "setter" propriété:
Par essence, il n'est pas opportun ni recommendable de publier une collection interne (ou objet interne ou structure interne) à l'aide d'un "setter", la disponibilité d'un "getter" étant amplement suffisant.
Un "getter" permet d'y accéder pour en modifier le contenu, c'est déjà largement suffisant.
Un "setter" permet de remplacer la référence de l'objet; autrement dit, de référé un autre objet créé par le développeur hors de la classe parente (l'instance de l'objet créé dans la classe devenant obsolète). Cela ouvre la porte a nombreux effets de bord et peu facilement devenir un cauchemar à débugger.

Modification de la classe CD

class CD {
    private List<CDTrack> _tracks;
    ...
    public List<CDTrack> Tracks { 
        get { return _tracks; }
        set {
            if (_tracks != null)
                _tracks = null; // free up current ressource
            _tracks = value;
        }
    }
    ...
}

Code d'initialisation
Avec cette dernière modification, le code d'initialization peut d'écrire comme suit:
List<CD> _CDs = new List<CD>();
_CDs.Add(new CD()
{
    Name = "This is it",
    Artist = "Jackson",
    Type = "Pop",
    Year = 2009,
    Info = "2/2",
    Tracks = new List<CDTrack>() { 
        new CDTrack { Name="I Just can't stop loving you", Seconds=139},
        new CDTrack { Name="Thriller", Seconds=308 },
        new CDTrack { Name="Beat It", Seconds=176}
    } 
});
Conclusion
Bien que le code ait acquis une bien meilleur lisibilité, je ne suis pas encore satisfait.
L'utilisation d'un "setter" pour publier la property "Tracks" ne me convient pas!

Troisième essais
Ce dernier essais se base sur le fait qu'une collection peut également être initialisée à l'aide d'un member initializer (les accolades {}).
Cela permet d'écrire l'initialization de façon encore plus claire sans nécessiter de "setter" pour la propriété Tracks.
De surcroit il n'est plus nécessaire d'ajouter les parenthèses derrière l'appel du constructeur.
Il est aussi possible d'écrite new CDTrack { Name="blabla" } au lieu de new CDTrack() { Name="blabla" }, cela améliore encore un peu plus la lisibilité.

Le nouveau code d'initialization devient donc:
List<CD> _CDs = new List<CD>();
_CDs.Add(new CD {
    Name = "History", Artist = "Jackson", Type = "Pop", Year = 2009, Info = "Continues, 2/2",
    Tracks =  { 
        new CDTrack { Name="Scream (duet with Janet Jackson)", Seconds=114},
        new CDTrack { Name="They don't care about us", Seconds=108 },
        new CDTrack { Name="Smile", Seconds=98},
        new CDTrack { Name="Money", Seconds=95}
    }
});
Conclusion
Cette dernière forme reste la meilleure option et celle que je retiendrais.
Cependant, il y a également les types anonymes (anonymous types apparu avec C# 3.0) dont la déclaration se rapproche le plus du langage Python.
Les types anonymes feront probablement l'objet d'un autre article.

Références

vendredi 8 janvier 2010

Initialiser une structure complexe en C# - petite étude sur la lisibilité de code - partie I

Introduction
En vue de m'exercer un peu à la manipulation d'objets XML sous .Net, j'ai voulu créer facilement une structure complexe en mémoire dans le but de pouvoir, par la suite, en faire un document XML.
J'ai donc choisi de décrire une collection de CD.

Puisque la structure était complexe, j'ai donc opté pour l'utilisation de classes et structures afin faciliter la création des éléments et essayer d'aboutir à un code LIMPIDE.
Le but étant de pouvoir, à terme utilisé des expressions LinQ et List.foreach pour m'aider à créer mon document XML.

En créant cette structure complexe, j'ai également voulu pouvoir l'initialiser facilement, rapidement mais SURTOUT en ayant un code FACILE A LIRE (et donc facile à maintenir).
Je voudrais aboutir à quelque-chose d'aussi clair que du code Python... car dans ce domaine, je dois avouer que Python dispose de quelques avantages.

Premier jet
A l'aide de la déclaration de CD et CDTrack (voir plus bas), il est possible d'initialiser ma collection avec le code suivant:

// Use a class structure to easily create structured data collection
List<CD> _CDs = new List<CD>();
_CDs.Add(new CD( new CDTrack() { Name = "Wonna Be startin' Somethin'", Seconds = 124 },
                  new CDTrack() { Name = "Jam", Seconds = 341 },
                  new CDTrack() { Name = "Human Nature", Seconds = 243 }
                 ) { Name="This is it", Artist = "Jackson", Type="Pop", Year=2009, Info="1/2" }
         );
_CDs.Add(new CD(new CDTrack() { Name = "Sophie", Seconds = 248 },
                  new CDTrack() { Name = "Friends", Seconds = 178 },
                  new CDTrack() { Name = "Le dictionnaire", Seconds = 86 },
                  new CDTrack() { Name = "L'as du lavabo", Seconds = 187 }
                 ) { Name = "Friends", Artist = "Tam-Tam", Type = "Capella", Year = 2007, Info = "Demo disc" }
         );

// Check the result:
foreach (CD cd in _CDs)
    Console.WriteLine(cd.ToString());

Conclusion
Bien que relativement compacte, le code de création reste un tantinet compliqué.
Les propriétés du CD arrivent après la création des instances de CDTrack.
Cela nuit de façon évidente à la lecture du code.

L'utilisation d'un "setter" pour la propriété Tracks permettrait certainement une écriture plus intelligible. C'est ce que je vais tester dès que possible. Je devrais également voir si les techniques de Class Inference peuvent faire quelque-chose pour moi.

Code des classes et structs
/// <summary>
/// Structure used to own information on a track
/// </summary>
struct CDTrack {
    public String Name { get; set; }
    public int Seconds{ get; set; }
}
/// <summary>
/// Class used to easily create a compact disk record
/// </summary>
class CD {
    private List<CDTrack> _tracks;

    public string Artist { get; set; }
    public string Type { get; set; }
    public int Year { get; set; }
    public String Name { get; set; }
    public String Info { get; set; }
    public List<CDTrack> Tracks { get { return _tracks; } }

    public CD() : base() {
        _tracks = new List<CDTrack>();
    }
    /// <summary>
    /// Create the description of a compact disk with Tracks.
    /// </summary>
    /// <param name="tracks">List of TrackName + TrackTime (in minutes)</param>
    public CD( params CDTrack[] tracks ):this(){
        foreach (CDTrack item in tracks)
            _tracks.Add(item);
    }

    public override string ToString()
    {
        String _Tracks;
        _Tracks = String.Join( "\n\t\t", 
                       (from cdtrack
                        in Tracks
                        select "TrackName: " + cdtrack.Name + ", seconds:" + cdtrack.Seconds.ToString()
                       ).ToArray<String>() ); 
        return base.ToString()+" having the properties: "+
            String.Format("\n  Name: {3}, Artist: {0}, Type: {1}, Year: {2}, Info: {4}",
                            Artist, Type, Year, Name, Info )+ "\n\t\t" + _Tracks;
    }
}

jeudi 7 janvier 2010

CodeRush XPress - Outil de productivité pour développeurs .Net

CodeRush Xpress est un puissant outil de productivité édité par Dev Express.
Le produit est gratuit, pour tous les utilisateurs de Visual Studio 2008 (sauf la version Express).

CodeRush Xpress inclut des fonctionnalités qui aide les développeurs dans les tâches de coding courantes.
Les apports de CodeRush concerne les domaines suivants:
  • Navigabilité dans le code (facilité la recherche, la sélection, la mise en évidence des blocs, etc).
  • Sélection et copier/coller intelligent de code.
  • Déclaration assistée (de type, variable, propriété, etc).
    CodeRush pourra, par exemple, déclarer une variable local et son type sur base de la sélection d'une méthode à l'aide d'intellisense.
  • Refactoring divers et variés (très complet d'ailleurs).
Un véritable outil de productivité qui viendra certainement faire le grand plaisir des accros du clavier.
Je vous invite a consulter ce très bel article de CodeRush expliquant, exemples à l'appui, les différentes possibilités.

Télécharger le Plug-in pour visual studio.

mercredi 6 janvier 2010

La civilisation, le pouvoir et la guerre au jour le jour

Je voudrais partager ici une réflexion concernant une nouvelle forme de "guerre au jour le jour" apparue au sein de notre société (dans les entreprises pour être plus précis).
Bien que nous vivons dans un pays civilisé et apparemment pacifique, une nouvelle forme de lutte (plutôt psychologique) est apparue cette dernière décennie.
Il ne fait aucun doute que la profonde modification des mentalités de notre société actuelle est à la source même de ce nouveau fléau.
Ce mal insidieux que l'on décrie de temps à autre et qui se range sans mal sous l' emblème du harcèlement psychologique, de la perversité, de la manipulation, etc fait lentement, mais sûrement, de nombreuses victimes.
Tous les coups sont permis pour les attaquants et notre système judiciaire est encore bien trop laxiste (immature ?  volontairement aveugle ?) dans ces domaines.
La comparaison avec "une guerre" est, me semble t'il, bien fondée.
Les victimes:
  • Sont nombreuses (bien au delà du dénombrement).
  • Souffrent souvent plus que mort (on s'attaque à ce qu'il y a d'humain).
  • Entraînent leur entourage dans la spirale de la dépression.
  • Sont détruites (de l'intérieur) avant même de comprendre ce qui se passe.
Le mieux reste encore d'être préparé... car les choses ne vont certainement pas s'arranger... le simple constat de la montée de la violence chez les jeunes gens (< 30 ans), une violence "incontrôlée" et libérée de toutes valeurs humanistes me semble être un bon indicateur de ce qui nous attends probablement dans un futur assez proche.


Je vous invite également à lire la citation reprise dans l'article de Francoise et directement issue du livre "In Tenebris" (la trilogie du mal) de Maxime Chattam. Cette réflexion axée autour de la nouvelle distribution des pouvoirs vaut vraiment la peine de s'y attarder.

Bonne lecture.

mardi 5 janvier 2010

Meilleurs voeux 2010

L'année 2010 s'annonce à nos portes et amène avec elle tous les espoirs de l'an neuf.
Que sur la route de vos projets, le soleil se mêle aux étoiles pour que vos voeux les plus cher deviennent réalité.
Que cette année vous offre d'agréables périodes d'amitiés, des instants de complicité exceptionnels et de riches occasions agrémentées de joies.
Que votre famille s'épanouisse dans le bonheur et déborde d'allégresse.
Que l'amour, la santé et l'amitié constituent le ciment de votre bien-être.