Управление доставкой динамического содержимого в Silverlight - Обработка содержимого XAP
ОГЛАВЛЕНИЕ
Обработка содержимого XAP
Класс Downloader использует WebClient для загрузки пакета XAP, а затем извлекает сборку, содержащую приложение, из сжатого потока и создает экземпляр указанного корневого класса. Вся эта логика спрятана за относительно простым программным фасадом, созданным из метода LoadPackage и события XapDownloaded. Этот метод имеет следующую сигнатуру.
public void LoadPackage(
string xapURL, string assemblyName, string className);
Он получает URL-адрес пакета, имя сборки, которую необходимо извлечь из пакета, и имя класса для создания его экземпляра. Как было упомянуто, этот класс является кодом поддержки файла интерфейса XAML.
Событие XapDownloaded запускается, когда класс загрузчика завершает обработку XAP и получает готовый для клиентского приложения пользовательский элемент управления. Приведем определение этого события.
public event
EventHandler<XapEventArgs> XapDownloaded;
Класс аргумента события возвращает следующую информацию.
public class XapEventArgs : EventArgs
{
public UserControl DownloadedContent;
}
Давайте разберем логику метода LoadPackage. Метод использует двоичный интерфейс класса WebClient для указания на пакет XAP.
void LoadPackage(string package, string asm, string cls)
{
assemblyName = asm;
className = cls;Uri address = new Uri(package, UriKind.RelativeOrAbsolute);
WebClient client = new WebClient();
client.OpenReadCompleted +=
new OpenReadCompletedEventHandler(OnCompleted);
client.OpenReadAsync(address);
}
Загрузка продолжается асинхронно и по завершении создает событие OpenReadCompleted. На рис. 5 показана реализация обработчика события.
Рис. 5 Загрузка завершена
void OnCompleted(object sender, OpenReadCompletedEventArgs e)
{
if (PackageDownloaded == null)
return;if (e.Error != null)
return;// Load a particular assembly from the XAP package
Assembly a = GetAssemblyFromPackage(assemblyName, e.Result);// Get an instance of the XAML object
object page = a.CreateInstance(className);// Fire the event
XapEventArgs args = new XapEventArgs();
args.DownloadedContent = page as UserControl;
XapDownloaded(this, args);
}
В отсутствие ошибок вспомогательная функция извлекает указанную сборку из пакета и получает требуемый для добавления экземпляр класса пользовательского элемента управления в фоновом коде блока XAML. Затем создается пользовательское событие для вызывающего кода, чтобы можно было обработать поддерево XAML. В этом месте остается обсудить следующее: детали того, каким образом сборка извлекается из сжатого потока, загруженного с URL-адреса. Этот код показан на рис. 6. Это стандартный код для извлечения сборки из пакета XAP. StreamResourceInfo и Application.GetResourceStream также широко используются для извлечения пакетов ресурсов, таких как изображения или мультимедийное содержимое, из текущего пакета XAP.
Рис. 6. Извлечение сборки из пакета XAP
Assembly GetAssemblyFromPackage(string assemblyName, Stream xap)
{
// Local variables
Uri assemblyUri = null;
StreamResourceInfo resPackage = null;
StreamResourceInfo resAssembly = null;
AssemblyPart part = null;// Initialize
assemblyUri = new Uri(assemblyName, UriKind.Relative);
resPackage = new StreamResourceInfo(xap, null);
resAssembly = Application.GetResourceStream(resPackage, assemblyUri);// Extract an assembly
part = new AssemblyPart();
Assembly a = part.Load(assemblySri.Stream);
return a;
}
Предполагается, что на пользовательской машине приложения Silverlight будут быстро загружаться и устанавливаться и быстро работать. Управляемый код работает лучше, чем интрепретируемый код JavaScript, поэтому производительность будет действительно высокой. Но, поскольку загрузка больших приложений Silverlight или приложений, требующих объемного внешнего графического или мультимедийного содержимого, может вызвать нежелательную задержку, ситуацию можно исправить, разбивая загрузку на несколько этапов. Еще лучше запрограммировать возможность проводить загрузку в несколько этапов по запросу.
Класс WebClient предлагает эффективный и асинхронный интерфейс программирования API для загрузки любых ресурсов, к которым можно получить доступ по Интернету. Расширяемая модель для объектной модели Silverlight позволяет быстро внедрять в существующую структуру любые изменения. Наконец, основанный на потоках интерфейс API, центральную роль в котором играет класс StreamResourceInfo, облегчает извлечение содержимого из ресурсов сборок и пакетов XAP.