silverlight assembly-resolution xap

Silverlight 4, carga dinámicamente de módulos xap



assembly-resolution (4)

Sé que es posible cargar módulos xap dinámicamente utilizando el marco Prism o MEF. Sin embargo, me gustaría no usar esos marcos; En su lugar, cargue mis archivos xap manualmente. Entonces, creé la siguiente clase (adaptada de internet):

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; } }

El código anterior funciona bien; Puedo cargar cualquier xap de la siguiente manera:

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

Ahora, tengo un UserControl llamado InvoiceView en el proyecto Sales.xap, por lo que me gustaría crear una instancia de la clase. En el proyecto actual (Main.xap) agregué referencia al proyecto Sales.xap, sin embargo, dado que lo cargo manualmente, configuro "Copiar local = falso". Pero cuando se ejecuta, el siguiente código arroja TypeLoadException:

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

Parece que el código no puede encontrar la clase InvoiceView. Pero comprobé que el método initXap () de XapLoader se ejecutó con éxito. Entonces, ¿por qué el código no puede encontrar la clase InvoiceView? ¿Puede alguien ayudarme con este problema?


Ok, encontré la causa. El código anterior funciona. Después de crear un nuevo proyecto Silverlight (Sales.xap), una vez compilé mi solución. Luego borré App class en Sales.xap y cambié el nombre de la clase MainPage predeterminada a SalesView. Sin embargo, no importa cuántas veces compile mi solución, el servidor web de desarrollo de Visual Studio estaba cargando la primera versión de Sales.xap (¿desde dónde?), Por lo que mi código no pudo encontrar SalesView. En mi proyecto Asp.Net de host, establecí el puerto del servidor de desarrollo en un número de puerto diferente, y el problema desapareció. Entonces el problema fue con el servidor de desarrollo de Visual Studio. Aparentemente mantiene los archivos compilados xap en alguna carpeta temporal, y no siempre actualiza esos archivos xap cuando cambia el código fuente.


Lo que hago para evitar estos problemas al ejecutar Silverlight recién compilado es borrar el caché del navegador, Chrome incluso tiene un claro caché Silverlight;)


este fenómeno de XAP Cache a menudo se debe al servidor web incorporado en el estudio visual (ASP.NET Development Server). Simplemente detenga la ocurrencia de este servidor y se borrará la caché. Comience de nuevo su proyecto y se llama a la última versión de su xap.


Esto se basa en la auto-respuesta del asker a continuación, en lugar de la pregunta.

Si elimina un proyecto / módulo, los archivos DLL / XAP de salida se almacenan. Si hace clic en el botón "mostrar todos los archivos", verá algunos de estos archivos de salida sobrantes en sus carpetas bin , bin y obj de proyectos relacionados.

Puede eliminarlos individualmente del proyecto o, en caso de duda, buscar todos los BIN y OBJ (por ejemplo, utilizando el explorador de escritorio) y eliminar todas esas carpetas. Las carpetas BIN / CLIENTBIN / OBJ se recrearán cuando sea necesario (¡este es el trabajo que debería haber hecho la opción "limpiar" en Visual Studio!)

Espero que esto ayude.