2010-09-09 18 views
6

So che è possibile caricare i moduli xap in modo dinamico utilizzando il framework Prism o MEF. Tuttavia, mi piacerebbe non usare questi framework; caricare invece i miei file xap manualmente. Così, ho creato la classe seguente (adattato da internet):silverlight 4, caricamento dinamico dei moduli xap

public class XapLoader 
{ 
    public event XapLoadedEventHandler Completed; 

    private string _xapName; 

    public XapLoader(string xapName) 
    { 
     if (string.IsNullOrWhiteSpace(xapName)) 
      throw new ArgumentException("Invalid module name!"); 
     else 
      _xapName = xapName; 
    } 

    public void Begin() 
    { 
     Uri uri = new Uri(_xapName, UriKind.Relative); 
     if (uri != null) 
     { 
      WebClient wc = new WebClient(); 
      wc.OpenReadCompleted += onXapLoadingResponse; 
      wc.OpenReadAsync(uri); 
     } 
    } 

    private void onXapLoadingResponse(object sender, OpenReadCompletedEventArgs e) 
    { 
     if ((e.Error == null) && (e.Cancelled == false)) 
      initXap(e.Result); 

     if (Completed != null) 
     { 
      XapLoadedEventArgs args = new XapLoadedEventArgs(); 
      args.Error = e.Error; 
      args.Cancelled = e.Cancelled; 
      Completed(this, args); 
     } 
    } 

    private void initXap(Stream stream) 
    { 
     string appManifest = new StreamReader(Application.GetResourceStream(
     new StreamResourceInfo(stream, null), new Uri("AppManifest.xaml", 
             UriKind.Relative)).Stream).ReadToEnd(); 

     XElement deploy = XDocument.Parse(appManifest).Root; 

     List<XElement> parts = (from assemblyParts in deploy.Elements().Elements() 
           select assemblyParts).ToList(); 

     foreach (XElement xe in parts) 
     { 
      string source = xe.Attribute("Source").Value; 
      AssemblyPart asmPart = new AssemblyPart(); 
      StreamResourceInfo streamInfo = Application.GetResourceStream(
       new StreamResourceInfo(stream, "application/binary"), 
       new Uri(source, UriKind.Relative)); 
      asmPart.Load(streamInfo.Stream); 
     } 
    } 
} 

public delegate void XapLoadedEventHandler(object sender, XapLoadedEventArgs e); 

public class XapLoadedEventArgs : EventArgs 
{ 
    public Exception Error { get; set; } 

    public bool Cancelled { get; set; } 
} 

Il codice di cui sopra funziona bene; Posso caricare qualsiasi xap seguente modo:

XapLoader xapLoader = new XapLoader("Sales.xap"); 
xapLoader.Completed += new XapLoadedEventHandler(xapLoader_Completed); 
xapLoader.Begin(); 

ora, ho un UserControl chiamato InvoiceView nel progetto Sales.xap, quindi vorrei creare un'istanza della classe. Nel progetto corrente (Main.xap) ho aggiunto un riferimento al progetto Sales.xap, tuttavia, poiché lo carico manualmente, imposto "Copy Local = False". Ma quando viene eseguito, il codice seguente getta TypeLoadException:

Sales.InvoiceView view = new Sales.InvoiceView(); 

Sembra che il codice non può trovare la classe InvoiceView. Ma ho controllato che il metodo initXap() di XapLoader fosse stato eseguito con successo. Quindi, perché il codice non riesce a trovare la classe InvoiceView? Qualcuno può aiutarmi con questo problema?

+0

Un modo più semplice per farlo è utilizzare il Managed Extensibility Framework (MEF) incorporato in Silverlight 4, oltre a .NET 4. –

risposta

1

Questo è basato sulla risposta automatica del richiedente, piuttosto che sulla domanda.

Se si elimina un progetto/modulo, i file DLL/XAP di output rimangono bloccati. Se fai clic sul pulsante "Mostra tutti i file", vedrai alcuni file di output rimanenti nel tuo client ,, bin e obj cartelle di progetti correlati.

alt text

È possibile eliminare singolarmente dal progetto, o, in caso di dubbio, la ricerca di tutti BIN e OBJ (per esempio usando l'esploratore desktop) ed eliminare tutte quelle cartelle. Le cartelle BIN/CLIENTBIN/OBJ verranno ricreate quando necessario (questo il lavoro che l'opzione "pulito" in Visual Studio avrebbe dovuto fare!)

Spero che questo aiuti.

+0

Ho scelto la risposta come corretta, tuttavia, ho notato che il menu Build-> Clean di Visual Studio non è stato di aiuto. Eliminare le cartelle bin/obj potrebbe aiutare (non l'ho ancora fatto), ma non voglio in modo ripetitivo, quindi attualmente ciò che sto facendo è modificare il numero di porta del server Web. A proposito, questo problema si verifica così spesso, anche quando non ho rinominato nulla. – synergetic

1

Ok, ho trovato la causa. Il codice sopra funziona. Dopo aver creato un nuovo progetto Silverlight (Sales.xap) mi è capitato di compilare una volta la mia soluzione. Quindi ho eliminato la classe App in Sales.xap e ho rinominato la classe MainPage predefinita in SalesView. Tuttavia, non importa quante volte ho compilato la mia soluzione, il server Web di sviluppo di Visual Studio caricava la prima versione di Sales.xap (da dove?), Quindi il mio codice non è riuscito a trovare SalesView. Nel mio progetto Asp.Net host ho impostato la porta del server di sviluppo su un numero di porta diverso e il problema è scomparso. Quindi il problema era con il server di sviluppo di Visual Studio. Apparentemente sta mantenendo i file xap compilati in una cartella temporanea e non aggiorna sempre quei file xap quando il codice sorgente è cambiato.

+0

Avevo lo stesso problema, stavo usando chrome - @Xds è giusto .Sembra che i problemi con i file xap di chrome caching siano grandi! Se apri una finestra di navigazione in incognito per lo stesso URL, vedrai le ultime modifiche (dato che l'incognito non memorizza nella cache). Inoltre, se si utilizza IExplorer per lo stesso url, verrà visualizzato l'ultimo - non viene memorizzato nella cache. Si spera che google chrome non memorizzi in modo così rigido lo xap. :( – DeeStackOverflow

0

Quello che faccio per evitare tali problemi durante l'esecuzione di appena compilato Silverlight è chiara la cache del browser, Chrome ha anche una cache silverlight chiara;) fenomeni Cache

0

questo XAP è spesso dovuto al server Web incorporato visual studio (ASP.NET Development Server). Basta interrompere l'occorrenza di questo server e la cache verrà cancellata. Ricomincia il tuo progetto e viene chiamata l'ultima build del tuo xap.

Problemi correlati