Caricamento differito di assembly o di porzioni di progetto in Silverlight 2.0

di Alessio Leoncini, in Silverlight 2.0,

Uno dei principi fondamentali da seguire durante lo sviluppo di un'applicazione web è quello di ridurre al minimo la quantità di dati da far scaricare all'utente durante l'uso del programma, in modo da diminuire i tempi di attesa e migliorare l'usabilità complessiva.

In un progetto Silverlight 2.0 è possibile scaricare l'interfaccia iniziale contenente le funzionalità principali e caricare successivamente le altre porzioni del progetto in funzione di precise azioni dell'utente o dell'applicazione stessa.

Un progetto Silverlight 2.0 è "impacchettato" in un file di tipo XAP che contiene sia gli assembly dell'interfaccia che quelli della logica applicativa. Dividendo il progetto in più file XAP è possibile eseguire il download di ciascun pacchetto con una semplice chiamata remota attraverso l'oggetto WebClient:

WebClient client = new WebClient();
client.OpenReadCompleted += new OpenReadCompletedEventHandler(client_OpenReadCompleted); 
Uri uriOfSecondXap = new Uri(GetBaseUri(), "ClientBin/SilverlightApplication2.xap");
client.OpenReadAsync(uriOfSecondXap);

Al termine del download del file XAP è necessario operare attraverso reflection per eseguire l'istanza sia dell'assembly principale che di quelli referenziati:

void client_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
{
    //recupero dello stream del file xap del progetto
    StreamResourceInfo resourceInfo = new StreamResourceInfo(e.Result, null);
    //Uri del manifest (contiene l'elenco degli assembly del progetto)
    Uri appManifestUri = new Uri("AppManifest.xaml", UriKind.Relative);
    //recupero dello stream del manifest 
    StreamResourceInfo manifestStream = App.GetResourceStream(resourceInfo, appManifestUri);
    //conversione in testo del manifest
    string appManifest = new StreamReader(manifestStream.Stream).ReadToEnd();

    //conversione del testo del manifest in struttura XML
    XElement appManifestRoot = XDocument.Parse(appManifest).Root;
    //estrazione della lista dei nomi degli assembly del progetto
    List<XElement> projectParts = (from parts in appManifestRoot.Elements().Elements()
                                   select parts).ToList();

    Assembly asm = null;

    //ciclo dei nodi del manifest
    foreach (XElement item in projectParts)
    {
        //nome dell'assembly
        string source = item.Attribute("Source").Value;
        Uri sourceUri = new Uri(source, UriKind.Relative);
        //recupero dello stream dell'assembly
        StreamResourceInfo appStream = App.GetResourceStream(resourceInfo, sourceUri);
        AssemblyPart asmPart = new AssemblyPart();

        if (source == "SilverlightApplication2.dll")
        {
            //qualora sia l'assembly principale:
            asm = asmPart.Load(appStream.Stream);
        }
        else
        {
            //nel caso di assembly referenziati dal principale:
            asmPart.Load(appStream.Stream);
        }
    }

    //per l'assembly principale si crea l'istanza dell'UserControl specifico utilizzando Reflection
    FrameworkElement element = asm.CreateInstance("SilverlightApplication2.Page") as FrameworkElement;
    //posizionamento dell'UserControl nella scena
    PlaceHolder.Children.Add(element);
}

Commenti

Visualizza/aggiungi commenti

| Condividi su: Twitter, Facebook, LinkedIn

Per inserire un commento, devi avere un account.

Fai il login e torna a questa pagina, oppure registrati alla nostra community.

Approfondimenti

Nessuna risorsa collegata

I più letti di oggi