Introduction

I. Situation sous Silverlight 2

Voici ce à quoi pouvait ressembler une solution Visual Studio pour un projet Silverlight 2 :

solution-without-caching.png

La solution d'exemple est composée d'un projet SilverlightApplicationLibraryCaching contenant l'application Silverlight, d'un projet MyCompany.Controls de type librairie contenant un ensemble de contrôles réutilisables (et référencé par l'application Silverlight) et d'un projet Web permettant d'héberger l'application Silverlight.

Lors de la compilation, Visual Studio génère un fichier xap unique contenant l'ensemble de l'application Silverlight et ses dépendances (librairies du SDK, du Silverlight Toolkit ou autres) dans le répertoire ClientBin. Vous pouvez visualiser le contenu du fichier xap en l'ouvrant avec un logiciel de lecture de fichier zip. Voici le contenu de ce fichier dans le cas de la solution présentée précédemment :

C:\Users\florian.casabianca\Documents\VirtualSharedFolder\xap-without-caching.png


Pour notre exemple, l'application Silverlight (SilverlightApplicationLibraryCaching.dll), la librairie de contrôles (MyCompany.Controls.dll) ainsi que la librairie du SDK utilisée (System.Xml.Linq) sont rassemblées au sein du fichier xap.

Le fichier AppManifest.Xaml référence la liste des librairies composant l'application :

Le fichier AppManifest.xaml avant la mise en place du cache
Sélectionnez
<Deployment xmlns="http://schemas.microsoft.com/client/2007/deployment" 
	  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
	  EntryPointAssembly="SilverlightApplicationLibraryCaching" 
	  EntryPointType="SilverlightApplicationLibraryCaching.App" 
	  RuntimeVersion="3.0.40624.0">
  <Deployment.Parts>
    <AssemblyPart x:Name="SilverlightApplicationLibraryCaching" 
	Source="SilverlightApplicationLibraryCaching.dll" />
    <AssemblyPart x:Name="MyCompany.Controls" Source="MyCompany.Controls.dll" />
    <AssemblyPart x:Name="System.Xml.Linq" Source="System.Xml.Linq.dll" />
  </Deployment.Parts>
</Deployment>

On y retrouve les trois librairies de notre exemple qui sont référencées comme étant internes au package xap.

Le problème avec cette méthode est que si vous mettez à jour votre application Silverlight (sans changer les librairies tierces, comme la librairie de contrôles de notre exemple), l'utilisateur devra re-télécharger l'intégralité du fichier xap avec toutes les librairies qu'il contient.

Silverlight 3 permet de résoudre ce problème en externalisant certaines librairies du fichier xap et en les mettant dans le cache du navigateur.

II. La mise en cache de librairies

Le principe de la mise en cache de librairies est le suivant :

  • La première fois que l'application Silverlight est lancée, le package xap ainsi que toutes les librairies externes associées sont téléchargés et mis dans le cache du navigateur. Les fichiers en cache sont réutilisés (si l'application n'a pas été mise à jour sur le serveur) à chaque fois que l'application Silverlight est ré-exécutée.
  • Lorsque le code de l'application Silverlight change, mais pas celui des librairies externes, alors seul le fichier xap est retéléchargé. Les librairies déjà dans le cache du navigateur sont réutilisées

Pour qu'une librairie puisse être mise en cache, vous devez la configurer en deux étapes :

La première est de fournir un nom fort à la librairie en la signant numériquement. Ceci ce fait via les propriétés du projet :

C:\Users\florian.casabianca\Documents\VirtualSharedFolder\signing-caching.png


La deuxième étape est de créer un fichier du même nom que la librairie avec l'extension « extmap.xml ». Ce fichier devra se trouver dans le même répertoire que la librairie (répertoire Debug et Release par exemple). Il suffit pour cela de créer ce fichier dans le projet de la librairie et de configurer ses propriétés « Build » à « None » et « Copy to the output directory » à « Copy always ».


Voici à quoi doit ressembler le contenu de ce fichier :

Fichier MyCompany.Controls.extmap.xml
Sélectionnez
<?xml version="1.0"?>
<manifest xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <assembly>
    <name>MyCompany.Controls</name>
    <version>1.0.0.0</version>
    <publickeytoken>4c76d4986e8099b6</publickeytoken>
    <relpath>MyCompany.Controls.dll</relpath>
    <extension downloadUri="MyCompany.Controls.zip" />
  </assembly>
</manifest>

Les noeuds name, version et publickeytoken correspondent aux métadonnées de la librairie et peuvent se retrouver via l'outil Reflector par exemple :

publictoken.png

Le noeud relpath indique le nom de la librairie.

L'attribut downloadUri du noeud extension indique l'endroit où trouver le package contenant la librairie. Vous avez la possibilité de saisir soit un nom de fichier, soit un URI.

Si vous indiquez un nom de fichier alors Visual Studio va automatiquement packager la librairie dans un fichier zip portant le nom indiqué. Ce package sera ensuite déployé à coté du fichier xap, dans le répertoire ClientBin du projet Web. La librairie ne sera donc plus intégrée au fichier xap mais packagée à coté.

Vous pouvez aussi indiquer un URI absolu (par exemple : http://mondomaine.com/monappli/1.0/MyCompany.Controls.zip). Dans ce cas, vous devrez vous-même packager la librairie et la déployer à l'URI indiqué. Si vous choisissez cette option, vous devrez faire attention aux appels cross-domain (si le package de la librairie se trouve sur un domaine différent de celui de l'application). Il sera aussi préférable de définir un URI différent pour chaque nouvelle version de la librairie.


Les librairies contenues dans le SDK de Silverlight 3 sont déjà configurées pour pouvoir être mises en cache. Vous pouvez vous en rendre compte en vous rendant dans le dossier « C:\Program Files\Microsoft SDKs\Silverlight\v3.0\Libraries\Client » :

linq-extmap.png


Maintenant que la librairie est configurée pour être mise en cache il ne reste plus qu'à indiquer à l'application Silverlight d'utiliser cette option. Pour cela il suffit de se rendre dans les propriétés de l'application Silverlight et de cocher la case « Reduce XAP file by using library caching ».

reduce-size-caching.png


Après recompilation, notre solution Visual Studio ressemble maintenant à ceci :

C:\Users\florian.casabianca\Documents\VirtualSharedFolder\solution-caching.png

Vous pouvez voir dans le projet Web que le dossier ClientBin contient maintenant trois fichiers : le fichier xap de l'application Silverlight et les packages zip correspondant aux librairies externalisées. Ces dernières ne sont plus contenues dans le fichier xap qui sera plus léger à télécharger par les utilisateurs :

C:\Users\florian.casabianca\Documents\VirtualSharedFolder\xap-with-caching.png


Le fichier AppManifest.xaml à lui aussi changé :

Le fichier AppManifest.xaml après la mise en place du cache
Sélectionnez
<Deployment xmlns="http://schemas.microsoft.com/client/2007/deployment" 
	  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
	  EntryPointAssembly="SilverlightApplicationLibraryCaching" 
	  EntryPointType="SilverlightApplicationLibraryCaching.App" 
	  RuntimeVersion="3.0.40624.0">
  <Deployment.Parts>
    <AssemblyPart x:Name="SilverlightApplicationLibraryCaching" 
	Source="SilverlightApplicationLibraryCaching.dll" />
  </Deployment.Parts>
  <Deployment.ExternalParts>
    <ExtensionPart Source="MyCompany.Controls.zip" />
    <ExtensionPart Source="System.Xml.Linq.zip" />
  </Deployment.ExternalParts>
</Deployment>

Les librairies MyCompany.Controls et System.Xml.Linq sont dorénavant référencées comme étant externes au package.


Le cache de librairies n'est pas utilisable avec la fonctionnalité « out of browser » permettant d'exécuter des applications Silverlight en dehors du navigateur. Si vous tentez d'utiliser les deux vous aurez droit à un message d'erreur de la part de Visual Studio :

error-out-browser-caching.png

III. Liens

Remerciements

J'adresse ici tous mes remerciements à l'équipe de rédaction de "developpez.com" pour le temps qu'ils ont bien voulu passer à la correction et à l'amélioration de cet article.

Contact

Si vous constatez une erreur dans le tutorial, dans les sources, dans la programmation ou pour toutes informations, n'hésitez pas à me contacter par le forum.