Développer cette année c’est forcément développer cross-plateforme. Mieux, c’est développer cross-form factor... Android, iOS, Windows 7, Windows 8, sur PC, tablette, smartphone... Un vrai casse-tête qui peut couter une fortune si on n’adopte pas dès le départ la bonne stratégie et les bons outils. C’est une stratégie opérationnelle avec ses outils que je vais vous présenter dans cette série de billets dont voici la première partie.More...
L'IPhone occupe de moins en moins de place sur le marché français où 60% des Smartphones sont des Android, mais malgré tout, comment développer pour ces plateformes dont les outils sont indigents ? En C# sous .NET ! Xamarin, la société fondée par le créateur de Mono (.NET sous Linux) vient enfin d’obtenir des financements à la hauteur. Miguel de Icaza avait déjà obtenu en 2011 une licence perpétuelle de la part Novell ce qui le mettait à l’abri d’avoir à repartir de zéro. Avec MonoDroid et MonoTouch la communauté C#/.NET dispose d’outils pas très chers pour développer sur mobile Apple ou Android. Cette levée de fond qui pérennise le travail de Xamarin est donc une excellente nouvelle pour tout le monde (article en anglais à lire) !
Noms de code : Jupiter, Mosh et Windows 8. Le dernier vous dit peut-être quelque chose, les deux premiers peut-être pas. Ensemble, ils pourraient signer l’avenir de Silverlight et rendre ce merveilleux outil un incontournable.More...
La plateforme .NET prend en charge l’Unicode et s’occupe parfaitement des problèmes de localisation pour les dates, les monnaies, ... Beaucoup pense qu’un tel système est suffisant pour assurer un bon fonctionnement de leurs logiciels sans se poser de question. Erreur. Et l’UX alors ?More...
Générer des nombres aléatoires avec un ordinateur est déjà en soit ambigu : un PC est une machine déterministe (heureusement pour les développeurs et les utilisateurs !) ce qui lui interdit l’accès à la génération de suites aléatoires aux sens mathématique et statistique. Toutefois il s’agit d’un besoin courant et .NET propose bien entendu une réponse avec la classe Random. More...
Visual Studio 2010 beta 2 est maintenant accessible au public et il devient donc possible de vous parler des nouveautés sans risque de violer le NDA qui courrait jusqu’à lors pour les MVP et autres early testers de ce produit.
Les évolutions du langage commencent à se tasser et la mouture 4.0 est assez loin des annonces fracassantes qu’on a pu connaître avec l’arrivée des génériques ou des classes statiques et autres nullables de C# 2.0, ni même avec LINQ ou les expressions Lambda de C# 3.0.
Pour la version 4 du langage on compte pour l’instant peu d’ajouts (le produit ne sortira qu’en 2010 et que d’autres features pourraient éventuellement apparaître). On peut regrouper les 3 principales nouveautés ainsi :
- Les type dynamiques (dynamic lookup)
- Les paramètres nommés et les paramètres optionnels
- Covariance et contravariance
Paramètres optionnels
Il est en réalité bien étrange qu’il ait fallu attendre 4 versions majeures de C# pour voir cette syntaxe de Delphi refaire surface tellement son utilité est évidente.
De quoi s’agit-il ? Vous avez tous écrits du code C# du genre :
1: MaMethode(typeA param1, typeB param2, typeC param3) …;
2: MaMethode(typeA param1, typeB param2) { MaMethode(param1, param2, null) }
3: MaMethode(typeA param1) { MaMethode(param1, null) }
4: MaMethode() { MaMethode(null) }
Et encore cela n’est qu’un exemple bien court. Des librairies entières ont été écrites en C# sur ce modèle afin de permettre l’appel à une même méthode avec un nombre de paramètres variable. Le Framework lui-même est écrit comme cela.
Bien sûr il existe “params” qui autorise dans une certaine mesure une écriture plus concise, mais dans une certaine mesure seulement. Dans l’exemple ci-dessus le remplacement des valeurs manquantes par des nulls est une simplification. Dans la réalité les paramètres ne sont pas tous des objets ou des nullables. Dans ces cas là il faut spécifier des valeurs bien précises aux différents paramètres omis. Chaque valeur par défaut se nichant dans le corps de chacune des versions de la méthode, pour retrouver l’ensemble de ceux-ci il faut donc lire toutes les variantes et reconstituer de tête la liste. Pas très pratique.
Avec C# 4.0 cette pratique verbeuse et inefficace prend fin. Ouf !
Il est donc possible d’écrire une seule version de la méthode comme cela :
1: MaMethode(bool param1=false, int param2=25, MonEnum param3 = MonEnum.ValeurA) …
Grâce à cette concision l’appel à “MaMethode(true)” sera équivalente à “MaMethode(true, 25, MonEnum.ValeurA)”. Le premier paramètre est fixé par l’appelant (c’est un exemple), mais les deux autres étant oubliés ils se voient attribuer automatiquement leur valeur par défaut.
Pas de surcharges inutiles de la méthode, toutes les valeurs par défaut sont accessibles dans une seule déclaration. Il reste encore quelques bonnes idées dans Delphi que Anders pourraient reprendre comme les indexeurs nommés ou les if sans nécessité de parenthèses systématiques. On a le droit de rêver :-)
Comme pour se faire pardonner d’avoir attendu 4 versions pour ressortir les paramètres par défaut de leur carton, C# 4.0 nous offre un petit supplément :
Les paramètres nommés
Les paramètres optionnels c’est sympa et pratique, mais il est vrai que même sous Delphi il restait impossible d’écrire du code tel quel “MaMethode(true,,MonEnum.ValeurA)”. En effet, tout paramètre doit recevoir une valeur et les paramètres “sautés” ne peuvent être remplacés par des virgules ce qui rendrait le code totalement illisible. C# 4.0 n’autorise pas plus ce genre de syntaxe, mais il offre la possibilité de ne préciser que quelques uns des paramètres optionnels en donnant leur nom.
La technique est proche de celle utilisée dans les initialiseurs de classe qui permettent d’appeler un constructeur éventuellement sans paramètre et d’initialiser certaines propriétés de l’instance en les nommant. Ici c’est entre les parenthèses de la méthode que cela se jouera. Pour suivre notre exemple précédent, si on veut ne fixer que la valeur de “param3” il suffit d’écrire :
1: MaMethode(param3 : MonEnum.ValeurZ);
de même ces syntaxes seront aussi valides :
1: MaMethode(true,param3:MonEnum.ValeurX);
2: MaMethode(param3:MonEnum.ValeurY,param1:false);
En effet, l’ordre n’est plus figé puisque les noms lèvent toute ambigüité. Quant aux paramètres omis, ils seront remplacés par leur valeur par défaut.
Voici donc une amélioration syntaxique qui devrait simplifier beaucoup le code de nombreuses librairies, à commencer par le Framework lui-même !
Dynamique rime avec Polémique
Autre nouveauté de C# 4.0, les types dynamiques. Aie aie aie…
Dynamique. C’est un mot qui fait jeune, sautillant, léger. Hélas. Car cela ne laisse pas présager du danger que représente cette extension syntaxique ! La polémique commence ici et, vous l’aurez compris, je ne suis pas un fan de cette nouveauté :-)
Techniquement et en deux mots cela permet d’écrire “MaVariable.MethodeMachin()” sans être sûr que l’instance pointée par MaVariable supporte la méthode MethodeMachin(). Et ça passe la compilation sans broncher. Si çà pète à l’exécution, il ne faudra pas venir se plaindre. Le danger du nouveau type “dynamic” est bien là. Raison de mes réticences…
Si on essaye d’être plus positif il y a bien sûr des motivations réelles à l’implémentation des dynamiques. Par exemple le support par .NET des langages totalement dynamiques comme Python et Ruby (les dynamique de C# 4 s’appuient d’ailleurs sur le DLR), même si ces langages sont plus des gadgets amusants que l’avenir du développement (avis personnel). Les dynamiques simplifient aussi l’accès aux objets COM depuis IDispatch, mais COM n’est pas forcément non plus l’avenir de .NET (autre avis personnel).
Les deux autres emplois des dynamiques qui peuvent justifier leur existence sont l’accès simplifié à des types .NET au travers de la réflexion (pratique mais pas indispensable) ou bien des objets possédant une structure non figée comme les DOM HTML (pratique mais à la base de pas mal de code spaghetti).
Bref, les dynamiques ça peut être utile dans la pratique, mais ce n’est pas vraiment une nouvelle feature améliorant C# (comme les autres ajouts jusqu’à maintenant). Le danger de supporter un tel type est-il compensé par les quelques avantages qu’il procure ? C’est là que dynamique rime avec polémique !
Pour moi la réponse est non, mais je suis certain que ceux qui doivent jongler avec du COM ou des DOM Html penseront le contraire.
J’arrête de faire le grognon pour vous montrer un peu mieux la syntaxe. Car malgré tout le dynamisme n’est pas une invitation au chaos. Enfin si. Mais un chaos localisé. C’est à dire que l’appel à une méthode non existante reste impossible partout, sauf pour un objet déclaré avec le nouveau type “dynamic” :
1: dynamic x;
2: x = Machin.ObtientObjetDynamique();
3: x.MethodeA(85); // compile dans tous les cas
4:
5: dynamic z = 6; // conversion implicite
6: int i = z; // sorte de unboxing automatique
7:
Bien entendu le “dynamisme” est total : cela fonctionne sur les appels de méthodes autant que sur les propriétés, les délégués, les indexeurs, etc.
Le compilateur va avoir pour charge de collecter le maximum d’information sur l’objet dynamique utilisé (comment il est utilisé, ses méthodes appelées…), charge au runtime du Framework de faire le lien avec la classe de l’instance qui se présentera à l’exécution. C’est du late binding avec tout ce qui va avec notamment l’impossibilité de contrôler le code à la compilation.
A vous de voir, mais personnellement je déconseille fortement l’utilisation des dynamiques qui sont comme un gros interrupteur ajouté en façade de C# “Langage Fortement Typé On/Off”. Restez dans le mode “On” et ne passez jamais en mode “Off” !
Covariance et Contravariance ou le retour de l’Octothorpe
J’adore le jargon de notre métier. “Comment passer pour un hasbeen en deux secondes à la machine à café” est une mise en situation comique que j’utilise souvent, certainement influencé par mon passé dans différentes grosses SSII parisiennes et par la série Caméra Café de M6…
Ici vous aurez l’air stupide lorsque quelqu’un lancera “Alors t’en penses quoi de la contravariance de C#4.0 ?”… L’ingé le plus brillant qui n’a pas lu les blogs intéressants la veille sera dans l’obligation de plonger le nez dans son café et de battre en retraire piteusement, prétextant un truc urgent à finir…
Covariance et contravariance sont des termes académiques intimidants. Un peu comme si on appelait C# “C Octothorpe”. On aurait le droit. Octothorpe est l’un des noms du symbole #. Mais franchement cela serait moins sympathique que “do dièse” (C# est la notation de do dièse en américain, à condition de prononcer le # comme “sharp” et non “square” ou “octothorpe”).
Un support presque parfait sous C# 1 à 3
Un peu comme monsieur Jourdain faisait de la prose sans le savoir, la plupart d’entre nous a utilisé au moins la covariance en C# car il s’agit de quelque chose d’assez naturel en programmation objet et que C# le supporte pour la majorité des types. D’ailleurs la covariance existe depuis le Framework 2.0 mais pour certains cas (couverts par C# 4.0) il aurait fallu émettre directement du code IL pour s’en servir.
C# 4.0 n’ajoute donc aucune nouvelle fonctionnalité ou concept à ce niveau, en revanche il comble une lacune des versions 1 à 3 qui ne supportaient pas la covariance et la contravariance pour les délégués et les interfaces dans le cadre de leur utilisation avec les génériques. Un cas bien particulier mais devant lequel on finissait pas tomber à un moment ou un autre.
Un besoin simple
C# 4.0 nous assure simplement que les choses vont fonctionner comme on pourrait s’y attendre, ce qui n’était donc pas toujours le cas jusqu’à lors.
Les occasions sont rares où interfaces et délégués ne se comportent pas comme prévu sous C#, très rares. Mais cela peut arriver. Avec C# 4.0 ce sont ces situations rares qui sont supprimées. De fait on pourrait se dire qu’il n’y a rien à dire sur cette nouveauté de C# 4.0 puisqu’on utilisait la covariance et la contravariance sans s’en soucier et que la bonne nouvelle c’est qu’on va pouvoir continuer à faire la même chose !
Mais s’arrêter là dans les explications serait un peu frustrant.
Un exemple pour mieux comprendre
Supposons les deux classes suivantes :
1: class Animal{ }
2: class Chien: Animal{ }
La seconde classe dérive de la première. Imaginons que nous écrivions maintenant un délégué définissant une méthode retournant une instance d’un type arbitraire :
1: delegate T MaFonction<T>();
Pour retourner une instance de la classe Chien nous pouvons écrire :
1: MaFonction<Chien> unChien = () => new Chien();
Vous noterez l’utilisation d’une expression Lambda pour définir le délégué. Il s’agit juste d’utiliser la syntaxe la plus concise. On pourrait tout aussi bien définir d’abord une fonction retournant un Chien, lui donner un nom, puis affecter ce dernier à la variable “unChien” comme dans le code ci-dessous :
1: public Chien GetChien()
2: {
3: return new Chien();
4: }
5:
6: MaFonction<Chien> unChien = GetChien; // sans les () bien sur !
7:
Partant de là, il est parfaitement naturel de se dire que le code suivant est valide :
1: MaFonction<Animal> animal = unChien;
En effet, la classe Chien dérivant de Animal, il semble légitime de vouloir utiliser le délégué de cette façon. Hélas, jusqu’à C# 3.0 le code ci-dessus ne compile pas.
La Covariance
La covariance n’est en fait que la possibilité de faire ce que montre le dernier exemple de code. C# 4.0 introduit les moyens d’y arriver en introduisant une nouvelle syntaxe. Cette dernière consiste tout simplement à utiliser le mot clé “out” dans la déclaration du délégué:
1: delegate T MaFonction<out T>();
Le mot clé “out” est déjà utilisé en C# pour marquer les paramètres de sortie dans les méthodes. Mais il s’agit bien ici d’une utilisation radicalement différente. Pourquoi “out” ? Pour marquer le fait que le paramètre sera utilisé en “sortie” de la méthode.
La covariance des délégués sous C# 4.0 permet ainsi de passer un sous-type du type attendu à tout délégué qui produit en sortie (out) le type en question.
Si vous pensez que tout cela est bien compliqué, alors attendez deux secondes que je vous parle de contravariance !
La Contravariance
Si la covariance concerne les délégués et les interfaces utilisés avec les types génériques dans le sens de la sortie (out), et s’il s’agit de pouvoir utiliser un sous-type du type déclaré, ce qui est très logique en POO, la contravariance règle un problème inverse : autoriser le passage d’un super-type non pas en sortie mais en entrée d’une méthode.
Un exemple de contravariance
Pas de panique ! un petit exemple va tenter de clarifier cette nuance :
1: delegate void Action1<in T>(T a);
2:
3: Action1<Animal> monAction = (animal) => { Console.WriteLine(animal); };
4: Action1<Chien> chien1 = monAction;
Bon, ok. Paniquez. !!!
Ici un délégué est défini comme une méthode ayant un paramètre de type arbitraire. Le mot clé “in” remplace “out” de la covariance car le paramètre concerné est fourni en entrée de la méthode (in).
La plupart des gens trouve que la contravariance est moins intuitive que la covariance, et une majorité de développeurs trouve tout cela bien complexe. Si c’est votre cas vous êtes juste dans la norme, donc pas de complexe :-)
La contravariance se définit avec le mot clé “in” simplement parce que le type concerné est utilisé comme paramètre d’entrée. Encore une fois cela n’a rien à voir avec le sens de “in” dans les paramètres d’entrée des méthodes. Tout comme “out” le mot clé “in” est utilisé ici dans un contexte particulier, au niveau de la déclaration d’un type générique dans un délégué.
Avec la contravariance il est donc possible de passer un super-type du type déclaré. Cela semble contraire aux habitudes de la POO (passer un sous-type d’un type attendu est naturel mais pas l’inverse). En réalité la contradiction n’est que superficielle. Dans le code ci-dessus on s’aperçoit qu’en réalité “monAction” fonctionne avec n’importe quelle instance de “Animal”, un Chien étant un Animal, l’assignation est parfaitement légitime !
M’sieur j’ai pas tout compris !
Tout cela n’est pas forcément limpide du premier coup, il faut l’avouer.
En réalité la nouvelle syntaxe a peu de chance de se retrouver dans du code “de tous les jours”. En revanche cela permet à C# de supporter des concepts de programmation fonctionnelle propres à F# qui, comme par hasard, est aussi fourni de base avec .NET 4.0 et Visual Studio 2010. Covariance et contravariance seront utilisées dans certaines librairies et certainement dans le Framework lui-même pour que, justement, les délégués et les interfaces ainsi définis puissent être utilisés comme on s’y attend. La plupart des développeurs ne s’en rendront donc jamais compte certainement… En revanche ceux qui doivent écrire des librairies réutilisables auront tout intérêt à coder en pensant à cette possibilité pour simplifier l’utilisation de leur code.
Et les interfaces ?
Le principe est le même. Et comme je le disais la plupart des utilisations se feront dans des librairies de code, comme le Framework l’est lui-même. Ainsi, le Framework 4.0 définit déjà de nombreuses interfaces supportant covariance et contravariance. IEnumerable<T> permet la covariance de T, IComparer<T> supporte la contravariance de T, etc. Dans la plupart des cas vous n’aurez donc pas à vous souciez de tout cela.
Lien
La documentation est pour l’instant assez peu fournie, et pour cause, tout cela est en bêta ne l’oublions pas. Toutefois la sortie de VS2010 et de .NET 4.0 est prévue pour Mars 2010 et le travail de documentation a déjà commencé sur MSDN. Vous pouvez ainsi vous référer à la série d’articles sur MSDN : Covariance and Contravariance.
Conclusion
Les nouveautés de C# 4.0, qui peuvent toujours changer dans l’absolu puisque le produit est encore en bêta, ne sont pas à proprement parler des évolutions fortes du langage. On voit bien que les 3 premières versions ont épuisé le stock de grandes nouveautés hyper sexy comme les génériques ou Linq qui ont modifié en profondeur le langage et décuplé ses possibilités.
C# 4.0 s’annonce comme une version mature et stable, un palier est atteint. les nouveautés apparaissent ainsi plus techniques, plus “internes” et concernent moins le développeur dans son travail quotidien.
Une certaine convergence avec F# et le DLR pousse le langage dans une direction qui ouvre la polémique. Je suis le premier a resté dubitatif sur l’utilité d’une telle évolution surtout que la sortie de F# accompagnera celle de C# 4.0 et que les passionnés qui veulent à tout prix coder dans ce style pourront le faire à l’aide d’un langage dédié. Mélanger les genre ne me semble pas un avantage pour C#.
C# est aujourd’hui mature et il est peut-être temps d’arrêter d’y toucher…
L’ensemble .NET est d’ailleurs lui-même arrivé à un état de complétude qu’aucun framework propriétaire et cohérent n’avait certainement jamais atteint.
.NET a tout remis à plat et à repousser les limites sur tous les fronts.
On peut presque affirmer que .NET est aujourd’hui “complet”. Même si la plateforme va encore évoluer dans l’avenir. Mais tous les grands blocs sont présent, des communications à la séparation code / IHM, des workflows aux interfaces graphiques et multitouch, de LINQ au Compact Framework.
Quand un système arrive à un haut niveau de stabilité, le prochain est déjà là, sous notre nez mais on le sait pas. Le palier atteint par .NET 4.0 marque une étape importante. Cet ensemble a coûté cher, très cher à développer. Il s’installe pour plusieurs années c’est une évidence (et une chance !). Mais on peut jouer aux devinettes : quelle sera la prochaine grande plateforme qui remplacera .NET, quel langage remplacera C# au firmament des langages stars pour les développeurs dans 10 ans ?
Bien malin celui qui le devinera, mais il est clair que tout palier de ce type marque le sommet d’une technologie. De quelle taille est le plateau à ce sommet ? Personne ne peut le prédire, mais avec assurance on peut affirmer qu’après avoir grimpé un sommet, il faut le redescendre. Quelle sera la prochaine montagne à conquérir ? Il y aura-t-il un jour un .NET 10 ou 22 ou bien quelque chose d’autre, de Microsoft ou d’un autre éditeur, l’aura-t-il supplanté ?
C’est en tout cas une réalité qui comme l’observation des espaces infinis qu’on devine dans les clichés de Hubble laisse songeur…
Rêver bien, mais surtout et pour les dix ans à venir : Stay Tuned !
La sérialisation est un besoin fréquent que le framework .NET sait parfaitement gérer. La sérialisation binaire s'obtient d'ailleurs le plus naturellement du monde en ajoutant un simple attribut [Serializable] à la définition de la classe. Mais voilà, essayez de décorer une classe avec SerializableAttribute sous Silverlight... Surprise ! Un message d'erreur vous prévient que l'espace de nom ne peut être trouvé.
Pas de sérialisation ?
Non. Pas de sérialisation binaire en tout cas sous Silverlight jusqu'à maintenant (v 3.0 au moment de ce billet). La classe SerializableAttribute n'est tout simplement pas définie dans System.
Avant d'aller crier au scandale sur les blogs ou forums officiels essayons de réfléchir...
A quoi sert la sérialisation ?
Sérialiser, cela sert à prendre un "cliché" d'une instance dans le but d'être capable de recréer une copie parfaite de cette dernière au bout d'un certain temps.
Un certain temps... cela peut être une milliseconde ou bien 1 jour ou 1 an. Dans le premier cas le stockage du "cliché" est en mémoire généralement, mais dans le second, il s'agit le plus souvent d'un stockage persistant tel qu'un fichier disque ou une base de données.
Pas de gestion de disque local en RIA
La nature même de Silverlight et le style bien particulier d'applications qu'il permet d'écrire fait qu'il n'existe aucune gestion de disque local. En réalité il n'existe rien qui permette d'accéder à la machine hôte, en lecture comme en écriture, question de sécurité.
On notera quelques exceptions à cette règle : l'OpenFileDialog qui permet d'ouvrir uniquement certains fichiers sur les disques de l'hôte et l'IsolatedStorage, espace de stockage local protégé pouvant être utilisé par une application Silverlight. Toutefois OpenFileDialog ne règle pas le problème de persistance et si l'IsolatedStorage peut être exploité en ce sens il s'agit d'un espace restreint, inlocalisable par un utilisateur "normal" donc in-sauvegardable sélectivement. Autant dire que l'IsolatedStorage peut rendre des services ponctuels (cache de données principalement) mais que ce n'est certainement pas l'endroit où stocker des données sensibles ou à durée de vie un peu longue.
Bref, en dehors de ces exceptions qui ne règlent pas tout à fait le besoin de persistance des instances, une application de type RIA ne peut sérieusement gérer des données que distantes...
En tout logique...
Reprenons : la sérialisation sert à persister des instances pour un stockage à plus ou moins longue échéance ou une communication avec un serveur distant. La nature d'une application RIA supprime la liberté d'un stockage local fiable et facilement maitrisable.
En toute logique sérialiser des instances sous Silverlight n'a donc aucun intérêt, sauf pour communiquer avec un serveur distant.
Comme le framework .NET pour Silverlight est une version light du framework complet il a bien fallu faire des coupes sombres... La sérialisation n'a pas échappé à cette rigueur. La principale raison d'être de la sérialisation sous Silverlight étant la communication (quelle que soit la technologie cela se fait sur une base XML le plus souvent) et cela réclamant une sérialisation XML plutôt que binaire, SerializableAttribute et sa sérialisation binaire ont ainsi été "zappés" !
Une solution
La situation est grave mais pas désespérée. S'il reste difficile le plus souvent d'utiliser directement sous Silverlight des classes conçues pour le framework complet (et pas seulement à cause de la sérialisation binaire), il est tout à fait possible de sérialiser des instances sous Silverlight à condition d'utiliser les mécanismes qui servent aux communications avec les serveurs distants.
Le DataContract
Silverlight utilise une partie du mécanisme WCF du DataContract (mais l'attribut DataMember n'existe pas). On trouve même une classe le DataContractSerializer qui fournit le nécessaire pour sérialiser et désérialiser des instances même si celles-ci ne sont décorées d'aucun attribut particulier.
Au final la sérialisation sous Silverlight est plus simple que la sérialisation binaire par SerializableAttribute sous le framework complet !
Un exemple de code
Einar Ingebrigtsen, un MVP nordiste travaillant en scandinavie, à eu la bonne idée de proposer deux méthodes utilitaires qui montrent comment utiliser le DataContractSerializer. Plutôt que d'imiter et réinventer la roue, regardons son code :
1: public string Serialize<T>(T data)
2: {
3: using (var memoryStream = new MemoryStream())
4: {
5: var serializer = new DataContractSerializer(typeof(T));
6: serializer.WriteObject(memoryStream, data);
7:
8: memoryStream.Seek(0, SeekOrigin.Begin);
9:
10: var reader = new StreamReader(memoryStream);
11: string content = reader.ReadToEnd();
12: return content;
13: }
14: }
15:
16: public T Deserialize<T>(string xml)
17: {
18: using (var stream = new MemoryStream(Encoding.Unicode.GetBytes(xml)))
19: {
20: var serializer = new DataContractSerializer(typeof(T));
21: T theObject = (T)serializer.ReadObject(stream);
22: return theObject;
23: }
24: }
C'est simple et efficace. Attention, pour utiliser ce code il faudra ajouter une référence à System.Runtime.Serialization.dll, puis un using System.Runtime.Serialization.
L'utilisation de ces méthodes tombe dès lors sous le sens, mais un petit exemple est toujours plus parlant :
1: { ....
2: // nouvelle instance
3: var t = new Test { Field1 = "test de serialisation", Field2 = 7 };
4: t.List.Add(new test2 { Field1 = "item 1" });
5: t.List.Add(new test2 { Field1 = "item 2" });
6: t.List.Add(new test2 { Field1 = "item 3" });
7:
8: // sérialisation et affichage
9: var s = Serialize<Test>(t);
10: var sp = new StackPanel { Orientation = Orientation.Vertical };
11: LayoutRoot.Children.Add(sp);
12: sp.Children.Add(new TextBlock { Text = s });
13:
14: // désérialisation et affichage
15: Var t2 = Deserialize<Test>(s);
16: var result = t2 == null ? "null" : "instantiated";
17: sp.Children.Add(new TextBlock { Text = result });
18: }
19:
20: // la classe de test
21: public class Test
22: {
23: public string Field1 { get; set; }
24: public int Field2 { get; set; }
25: private ObservableCollection<test2> list =
26: new ObservableCollection<test2>();
27: public ObservableCollection<test2> List { get { return list; } }
28: }
29:
30: // la classe des éléments de la liste de la classe Test
31: public class test2
32: {
33: public string Field1 { get; set; }
34: }
Conclusion
Une fois que l'on a compris pourquoi la sérialisation binaire est absente de Silverlight, et une fois qu'on a trouvé une solution de rechange, on se sent beaucoup mieux :-)
Il reste maintenant tout à fait possible de stocker en local le résultat de la sérialisation dans un fichier texte (en utilisant l'IsolatedStorage sur lequel je reviendrai) ou bien de le transmettre à service Web ou autre...
Stay Tuned !
Les applications Silverlight ont le même besoin que les autres d'être testées ! Et même s'il reste possible de tester de façon séparée tous les objets métiers (en utilisant le Unit Testing de Visual Studio), tester une application Silverlight en cours de fonctionnement ne s'avérait pas tout aussi simple.
Unit Test Framework for Silverlight
Ce Framework est une solution construite par des développeurs pour des développeurs, pour les aider à construire des applications riches et des composants pour Microsoft Silverlight 2. Le Framework est actuellement disponible en tant que binaires téléchargeables à utiliser dans vos propres applications. Microsoft avait d'abord sorti ce Framework avec le code source et les tests unitaires pour les contrôles Silverlight lors de la conférence MIX'08 à Las Vegas.
Compatibilité
Le Framework de tests unitaires est compatible avec Microsoft Silverlight 2. Il est utilisable sous Windows et Mac. Et il tourne sous les navigateurs suivants: Safari, Mozilla Firefox, et Internet Explorer.
Que demander de plus ? !
Simple, puissant et extensible
Le Framework permet :
-
d'exécuter des tests unitaires à l'intérieur du navigateur Web
-
de tester les contrôles riches et l'ensemble de la plate-forme Silverlight
-
de faire des tests asynchrones
Plus d'information
Téléchargements
Dans la jungle du Framework et de tous ses projets satellites qui sortent au rythme d'une rafale d'AK47 comment un pauvre développeur isolé peut-il intégrer et digérer en quelques heures (en plus de son travail quotidien) des centaines, voire des milliers d'années-homme de librairies, technologies, outils et langages produits par Microsoft ?
C'est une véritable question. Dans mon propre travail de conseil je m'oblige à une réserve de 30% de mon temps uniquement dédié à la veille technologique, c'est à dire qu'un tiers de mon temps n'est jamais vendu, je me le réserve pour apprendre, un luxe indispensable mais coûteux en chiffre d'affaire potentiel perdu. De plus c'est un mode de fonctionnement que seul un dirigeant d'entreprise ou un indépendant peut s'offrir. Et malgré ce privilège tous les jours je mesure l'étendue de mon ignorance sur certains aspects du Framework avec la désagréable impression que plus je rame plus la côte s'éloigne ... Je suis certain de n'être pas le seul à ressentir cette sensation !
Il y a ceux qui ont d'emblée choisi de se spécialiser. Ils connaissent tout ou presque de Windows Forms, de WPF, ou de Silverlight mais ignore tout des dizaines d'autres éléments du Framework. Impasse sur ASP.NET, Ajax, MVC, Entity Framework, etc, etc. Chacun fait alors son petit marché n'ayant au final qu'une vue très restreinte sur le Framework, et, de fait, loupant souvent d'excellentes choses. Hélas une journée n'a que 24h, et pour avoir essayer par tous les moyens de contourner sans succès cette terrible réalité, je peux affirmer que travailler, même beaucoup, même trop, n'est pas forcément la solution. Seule Zenon d'Elée arrivait dans son paradoxe à faire gagner une tortue face à Achille ! Quand l'adversaire est en supériorité, la force brute est inutile, il faut ruser...
Microsoft a conscience de ce problème. Qu'il s'agisse des petites vidéo "how do I", des multiples conférences qui se tiennent régulièrement, de la documentation très fournie de MSDN, de l'excellent magazine MSDN toujours riche d'articles de haute tenue technique, et de bien d'autres actions en faveur de la diffusion de la connaissance sur ses produits, Microsoft fait beaucoup pour nous aider à appréhender l'étendue de sa gamme.
Si cet effort louable est important, on peut toujours en réclamer plus. Par exemple une certaine décentralisation de toutes ces informations fait que peu de gens connaissent tous les "points d'entrée" utiles de ces informations. Gageons que Microsoft en a aussi conscience et que des efforts supplémentaires seront réalisés pour aider le développeur "à s'y retrouver dans les informations qui permettent de s'y retrouver" dans les produits...
Patterns & Practices
Tout cela pour vous parler aujourd'hui des Patterns & Practices. Il s'agit d'un ensemble de recommandations et de code mis à disposition gratuitement sur CodePlex. Bien connaître ces "patrons et pratiques" peut vous aider à mieux tirer partie du Framework sans pour autant y consacrer vos nuits.
Pour obtenir la liste de tous les projets gravitant autour de ce concept de "patterns & practices" allez sur CodePlex et chercher cette expression. Vous pouvez aussi directement accéder à tous les projets pertinents par le tag du même nom (colonne de droite sur CodePlex).
Les projets clé
Il est bien entendu très difficile de créer un ordre de priorité dans tous les projets "patterns & practices", selon ce que vous développez, l'urgence de regarder tel ou tel projet sera plus ou moins grande. Mais je vais tenter une petite sélection de ceux qui, à mon sens, sont à connaître absolument.
App Arch Guide 2.0 Knowledge base
http://www.codeplex.com/AppArch
Ce projet initié par JD Meier, Jason Taylor et Prashant Bansode regroupe de nombreux documents et vidéos dont le but est d'expliquer "How to put the legos together", ce dont je parlais plus haut : savoir comment utiliser correctement toutes les briques de constructions du Framework pour en faire quelque chose.
The purpose of the Application Architecture Guide 2.0 is to improve your effectiveness building applications on the Microsoft platform. The primary audience is solution architects and developer leads. The guide will provide design-level guidance for the architecture and design of applications built on the .NET Framework. It focuses on the most common types of applications, partitioning application functionality into layers, components, and services, and walks through their key design characteristics.
Ce projet est certainement le premier point d'entrée que vous devez connaître. Sa vision globale de l'architecture des applications vous aidera à prendre de meilleures décisions.
Application Architecture Guide 2.0 (le livre)
http://www.codeplex.com/AppArchGuide
Ce guide fournit des guides architecturaux pour la création d'applications .NET. Les principaux types d'applications sont étudiés et de nombreuses solutions sont proposées.
Le livre complète la "App Arch Guide 2.0 Knowledge base" décrite ci-dessus.
Enterprise Library
http://www.codeplex.com/entlib
http://msdn.microsoft.com/fr-fr/library/cc467894(en-us).aspx
L'Enterprise Library est une collection de blocs applicatifs qui ont été conçus pour assister le développeur dans son travail. Il s'agit de code mais d'une certaine façon ce code constitue un guide des bonnes pratiques.
Le code source est fourni avec une documentation. EL peut être utilisé tel quel ou bien modifié ou étendu.
Constitué de plusieurs "blocs", EL est une vraie mine d'or. Gestion du caching, cryptographie, accès aux données, gestion des exceptions, logging, sécurité, des solutions pratiques, génériques et éprouvées sont apportées à chacun de ses sujets.
Un "must have" donc. (et surtout un "must understand" !).
Web Client Software Factory
http://www.codeplex.com/websf
le WCSF fournit un ensemble de directives pour les architectes et les développeurs d'applications Web. La factory inclue des exemples, du code réutilisable et un ensemble de guidlines pour automatiser les tâches clé du développement sous Visual Studio. Pour ceux qui connaissaient, WCSF remplace UIP (User Interface Process Application Block). WCSF supporte bien entendu les nouveautés du Framework comme ASP.NET, Ajax ou Workflow Foundation.
A connaître dès lors qu'on veut développer des applications Web...
Composite WPF and Silverlight
http://www.codeplex.com/CompositeWPF
Ce bloc des patterns & practices fait partie du top 5 à connaître et maîtriser. Il intègre code et guidelines nécessaires à la mise en place d'architectures suivant les best practices pour les projets de type WPF et Silverlight. Tout est bon, il faut absolument le connaître !
A noter: ce projet est aussi connu sous le nom de "Prism" (info primordiale surtout pour faire le cador à la machine à café :-) ).
Smart Client Guidance
http://www.codeplex.com/smartclient
http://msdn.microsoft.com/en-us/library/aa480482.aspx
Le Smart Client Software Factory (SCSF) est une autre guide essentiel. Guidelines et code forment un ensemble de composants réutilisables sous Windows Forms autant que WPF ou ASP.NET pour mettre en place une architecture de client intelligents composites.
Je n'ai pas eu encore le temps de plonger dans ce guide, mais du survol que j'en ai fait, il faut très certainement le regarder de plus près, les solutions proposées semblent tout aussi indispensables à connaître que les autres guides de la série "patterns & practices".
Unity
http://www.codeplex.com/unity
Encore un guide que je n'ai pas eu le temps de lire... Les longues soirées d'hiver sont un mythe : il fait nuit plus tôt mais les journées ne comptent toujours pas plus de 24h, cette expression est donc une escroquerie ! :-)
The Unity Application Block (Unity) is a lightweight extensible dependency injection container with support for constructor, property, and method call injection.
Dit comme ça, c'est un peu confus... pour tout savoir le mieux c'est de lire (le conseil vaut pour moi aussi) !
WCF Security Guidance
http://www.codeplex.com/WCFSecurity
La mise en place de services via WCF peut se faire de façon très naïve... ou de façon professionnelle, c'est à dire en gérant correctement la sécurité ! Ce guide fait le tour de la question et propose des guidelines autant que du code pour mieux sécuriser les applications communiquantes et gérer correctement les authentifications, les autorisations et toutes ces choses indispensables pour des applications mises en production.
Web Service Software Factory
http://www.codeplex.com/servicefactory
Il s'agit d'une collection d'outils, de patterns, de code source et de guidelines destinés à vous aider à construire des Web services WCF et ASMX rapidement mais en garantissant la meilleure fiabilité possible.
Indispensable comme le reste...
Guidance Explorer
http://www.codeplex.com/guidanceExplorer
Voici peut être un moyen de s'y retrouver un peu mieux parmi toutes les guidelines ! le Guidance Explorer, comme son nom l'indique, est un outil d'exploration des guidelines. Une fois installé il se met à jour via le Web.
Centralisant bon nombre de guides et simplifiant l'accès à l'information, Guidance Explorer est l'une des premières choses à installer à côté de Visual Studio !
MS Health Common User Interface
http://www.codeplex.com/mscui
C'est un peu l'ovni de cette liste et même un vrai ovni à part entière dans tout le Framework et les guidelines. On se demande pourquoi Microsoft a investi dans cette branche très spécialisée plutôt qu'une autre. Le MSCUI est en effet un ensemble de guidelines, de code et de composants permettant de réaliser des application orientées médical. Composants WCF, Silverlight ou autres, c'est un ensemble incroyable quantitativement et qualitativement. Ayant été l'un des pioniers de l'informatique médicale en France avec la gamme de logiciel Hippocrate je connais particulièrement bien la question et j'ai été bluffé par ce que propose MS avec MSCUI. Avec cet outil un bon développeur peut assez rapidement mettre en place des solutions tout à fait honorables capables de concurrencer les principaux logiciels médicaux du marché...
Si le médical n'est pas votre branche, MSCUI ne vous intéressera que peu dans la pratique, mais regardez tout de même comment cela est fait et comment les composants se présentent, ergonomiquement et fonctionnellement c'est un beau travail.
Conclusion
Si ce tour d'horizon n'est pas exhaustif il contient malgré tout le top des guidelines et outils à connaître pour développer sereinement des solutions basées sur des patterns éprouvées. Ne pas réinventer la roue, mettre rapidement en place la bonne architecture d'un projet c'est déjà s'assurer à 50% de sa réussite.
Si les soirées d'hiver ne comportent pas plus d'heures que celles d'été, la froidure incite moins à sortir et à flâner qu'en août, profitez-en pour rester au chaud en vous plongeant dans les Patterns & Practices !
N'oubliez pas ce vieux proverbe qui nous vient du fond des âges :
"L'hiver, qui bouquine Patterns & Practice,
l'été, produit du code qui glisse !"
Et Stay Tuned !
Il y a encore quelques jours je vous informais de la mise à jour française des outils pour Silverlight 2 et j'en profitais pour rappeler qu'il s'agit d'une solution multi plateforme unique en son genre. Une voix s'est fait entendre pour rappeler que sous Linux ce n'est pas encore au niveau de SL 2, c'est vrai. Mais preuve de ce dynamisme multi plateforme c'est maintenant au tour de Silverlight pour Mobile d'être annoncé par MS !
Et l'avancée est de taille puisque il n'y aura pas besoin de modifier son code pour qu'une application SL puisse tourner sur Mobile, même si elle utilise des vidéos. C'est incroyable quand on sait que sur un Mobile la place est réduite pour arriver à y faire entrer le framework .NET, même la version allégée de SL. Prouesse technique donc. Et encore plus d'ouverture pour les développeurs.
Autre annonce de taille, Silverlight est pour l'instant une technologie "navigateur", mais il semble que les équipes en charge de ce produit désire le faire évoluer en quelque chose de stand-alone, hors de tout navigateur. Une plateforme .NET multi OS fonctionnant directement sur Mac, PC, Linux, Mobile ? Il est vrai que techniquement il "suffit" de se passer du browser. Mais quelle perspective ! Avec WCF et les sockets pour la communication la panoplie semble alléchante.
Pour ce qui est des plateformes mobiles supportées, on retrouve bien entendu Windows Mobile 6.x. Là aussi, bien que les choses ne soient pas arrêtées, il semblerait que le support Windows Embedded CE soit sous le coude des développeurs SL...
Si vous voulez en savoir plus je vous conseille la video de "Silverlight 2 for Mobile" enregistrée aux dernières PDC et déjà diffusée sur le célèbre Channel 9 !