Chargement d’assembly externe en Silverlight 2
Quand une application commence à grossir en Silverlight c’est un seul et même fichier qui grossi. L’idée de ce billet est de montrer comment on peut découper l’application Silverlight en plusieurs XAP et de permettre un chargement différé des assembly contenant, ou des DLL, ou des ressources.
Il faut dans un premier temps découper l’application en Library:
Ici on a une class “ClassExternal” avec une methode “Somme”
namespace SilverlightLibraryExternal
{
public class ClassExternal
{
public int Somme(int i, int j)
{
return i + j;
}
}
}
Puis, de l’application Silverlight il faut référencer la library “SilverlightClassLibrary” mais avec l'option “Copy local” à False
Ce qui permet d’avoir accès a l’espace de nom pour la compilation mais de pas intégrer la Dll dans le XAP de l’application finale.
Il faut donc charger la Dll au moment de l’exécution. Mais le mieux, c’est d’encapsuler cette Dll dans un zip (un fichier XAP) pour respecter le packaging de Silverlight 2.
Pour ce faire on peut utiliser plusieurs utilitaire j’ai pris “Chiron.exe” qui est dans le SDK de la DLR ici : https://www.codeplex.com/sdlsdk
J’ai donc rajouter 2 directives de post-compilation du projet “SilverlightLibraryExtenal”
"C:\Program Files\Microsoft SDKs\Silverlight\sdlsdk\bin\Chiron.exe" /x:$(TargetName).xap
copy "$(TargetName).xap" "$(SolutionDir)SilverlightApplicationLoadExternalAssembly.Web\ClientBin\"
Ce qui donne après compilation dans le répertoire ClientBin deux fichiers XAP
Passons au chargement dynamique de cette library:
La class StreamRessourceInfo permet de lire le contenu du XAP et la class AssemblyPart permet de charger un library dynamiquement.
L’option “NoInlining” de l’attribut “MethodImpl” spécifie que la méthode ne peut pas être “inlined” dans cette méthode il ne faut pas faire référence au Type externe, d’où l’utilisation de la méthode UseLibraryExternal qui fait simplement un Cast.
Une fois que tout ceci est fait on peut activer le bouton qui fait simplement un appel à la methode “Somme” l’avantage c’est que le développeur a l’aide à la saisie au moment du développement et aussi la vérification de type au moment de la compilation. On a simplement différé le chargement de l’assembly.
public partial class Page : UserControl
{
ClassExternal ext;
public Page()
{
InitializeComponent();
//Chargement du XAP
WebClient wc = new WebClient();
wc.OpenReadCompleted +=
new OpenReadCompletedEventHandler(wc_OpenReadCompleted);
wc.OpenReadAsync(new Uri("SilverlightLibraryExternal.xap",
UriKind.Relative));
}
private void Button_Click(object sender, RoutedEventArgs e)
{
MessageBox.Show(ext.Somme(2, 2).ToString());
}
void wc_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
{
StreamResourceInfo zip = new StreamResourceInfo(e.Result, null);
//Extration de la DLL du ZIP
StreamResourceInfo manifestInfo =
Application.GetResourceStream(zip,
new Uri("SilverlightLibraryExternal.dll", UriKind.Relative));
AssemblyPart part = new AssemblyPart();
//Chargement de l’assembly
Assembly a = part.Load(manifestInfo.Stream);
object o = CreateSLClassLibraryExternal();
UseLibraryExternal(o);
//Activation du bouton
bt1.IsEnabled = true;
}
//Methode non linker statiquement
[System.Runtime.CompilerServices.MethodImpl
(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
private object CreateSLClassLibraryExternal()
{
return new SilverlightLibraryExternal.ClassExternal();
}
private void UseLibraryExternal(Object o)
{
ext = (ClassExternal)o;
}
}
Ce qui donne bien deux chargement de XAP :
Et le résultat attendu
Source du projet
Source : Cool Silverlight Trick #3, Downloading Zipped files with the WebClient, MSDN MethodImplAttributes Enumeration
Comments
- Anonymous
January 24, 2009
Ce sujet est assez bien couvert dans les différents billets sur Silverlight, mais je l’aborde de nouveau