I. Pourquoi partager du code ?

La question est assez simple, la réponse l'est tout autant : la factorisation ! Il est très contraignant de devoir maintenir deux codes identiques. Bien souvent, on met à jour l'un en oubliant l'autre, il y a des problèmes de synchronisation, bref une belle source de bugs !
Il y a également une problématique bien connue des personnes utilisant du Silverlight : les proxys de services Web générés pas Visual Studio. Prenons notre solution de test : nous exposons trois services et trois entités différents comme ci-dessous.
Image non disponible

Lorsque Visual Studio génère les proxys, on s'aperçoit d'une chose étrange : une même entité côté serveur correspond à plusieurs entités côté client (une par proxy de service) !
Image non disponible

Bien sûr, ces entités ne sont pas compatibles entre les namespaces, ce qui peut poser problème dans l'utilisation de celles-ci. Nous allons donc créer une librairie qui contient nos entités côté client dans le chapitre suivant.

II. Partager du code "avec les moyens du bord"

D'une manière naïve, nous pourrions essayer d'ajouter au projet Silverlight une référence vers le projet de nos entités. Cela n'est pas possible, ils ne sont pas destinés à la même plateforme. Il faut donc créer un nouveau projet Silverlight qui contient le même code que la version .Net. Toujours d'une manière naïve, nous pourrions copier-coller le code entre les deux projets : cela s'avère peu efficace et bien souvent source de bugs ! Nous pouvons donc ruser un peu : au lieu de copier le code, dans le nouveau projet, nous allons ajouter les fichiers en tant que lien. Ils ne seront présents que logiquement et non pas physiquement.
Image non disponible

Désormais, les fichiers apparaissent avec une petite flèche de raccourci et il est possible de faire une référence sur ce projet depuis l'application Silverlight. Reste à dire lors de la création d'un proxy qu'il faut utiliser ces entités : c'est fait automatiquement par Visual Studio si la référence est correcte.
Cependant, bien que cela soit la meilleure solution qui existait, elle n'était pas parfaite : même s'il ne fallait plus se soucier du contenu des fichiers, il fallait toujours penser à répliquer l'ajout/déplacement des fichiers. Là encore, cela pouvait être source de bug. C'est pour cela que sont arrivés les Portable Library Tools.

III. Principe et utilisation de la Portable Class Library

La Portable Class Library est un nouveau type de projet apporté par les Portable Library Tools (extension Visual Studio disponible ici). Un projet de ce type pourra être référencé à la fois par un projet .Net standard mais également un projet Silverlight, Windows Phone 7 et XNA.
Bien sûr, cela ne va pas sans contraintes : le framework XNA n'est pas aussi complet que .Net, il faut donc faire attention à la partie du framework qui est utilisée. Voici un tableau extrait de MSDN qui résume les possibilités :

Fonctionnalité Assemblies .NET Silverlight Windows Phone 7 XNA
Core mscorlib.dll, System.dll, System.Core.dll, System.Xml.dll Oui Oui Oui Oui
Managed Extensibility Framework (MEF) System.ComponentModel.Composition.dll Oui Oui Non Non
Network Class Library (NCL) System.Net.dll Oui Oui Oui Non
Serialization System.Runtime.Serialization.dll Oui Oui Oui Non
Windows Communication Foundation (WCF) System.ServiceModel.dll Oui Oui Oui Non
XML Serialization System.Xml.Serialization.dll Oui Oui Oui Non
View Model Support System.Windows.dll (from Silverlight) Non Oui Oui Non

Il faut par conséquent déterminer quelles sont les plateformes qui nous intéressent et les configurer dans les options du projet, comme ci-dessous.
Image non disponible

Désormais, nous pouvons utiliser ce projet et le référencer à la fois dans notre couche service côté serveur et dans notre application côté Silverlight.

Il est à noter que cet outil nécessite une mise à jour du Framework 4 (déployé lors de l'installation du SP1 de Visual Studio) disponible ici. Il est également nécessaire d'avoir Silverlight au moins en version 4.0.60129.0.

Il est à noter également que l'utilisation de ObservableCollection<T> n'est pas possible lorsque le framework .NET 4 est en cible car cette classe n'est pas dans les mêmes assemblies sur Silverlight et .NET 4

IV. Conclusion

On voit clairement une nouvelle fois la stratégie trois écrans (PC, WP7 et XBOX360) de Microsoft : proposer le même contenu sur tous les appareils possibles. D'une manière assez conviviale, on peut désormais partager nos entités entre le serveur et le client Silverlight/WP7 ou partager les ViewModels entre Silverlight et WP7 lors de l'utilisation du MVVM. Les sources sont disponibles sur ce lien.
Merci à jacques_jean pour sa relecture attentive.