Silverlight实用窍门系列:31.Silverlight中WebClient+StreamResourceInfo+反射实现动态加载外部XAP程序【附带源码】

        在Silverlight中我们时常会遇到需要加载其他已经制作完成的Silverlight程序的情况,在本节中我们使用WebClient下载XAP包形式的Silverlight程序,然后使用反射的方式解析出这个Silverlight的程序加载到本Silverlight程序中。步骤如下:

        1 •首先我们使用WebClient类的OpenReadAsync(Uri)方法读取某个Uri位置的XAP文件,可以得到这个XAP的Stream值。

        2 •使用Application.GetResourceStream(StreamResourceInfo, Uri)从指定 zip/XAP 包中的某个位置返回资源文件。(这个函数有两个参数:第一个参数是new StreamResourceInfo(Stream)获取到WebClient下载下来的XAP Stream。第二个参数:在这个XAP包中的某一个位置的需要运行的文件的DLL的Uri。)

        3 •上一步骤运行函数Application.GetResourceStream得到的返回值也是一个StreamResourceInfo类型的值,将此值运行.Stream属性获取到它的Stream流。

        4 •AssemblyPart.Load(Stream)方法将 Stream 转换为随后将加载到当前应用程序域中的 Assembly。

        5 •(UserControl)assembly.CreateInstance(mainStr)根据mainStr名从此程序集中查找指定的类型,然后使用系统激活器创建它的实例。

        下面我们创建一个名为SLoadXAP的Silverlight应用程序,在SLoadXAP.Web项目的ClientBin文件夹中,放入第29节中我们制作成功的雷达XAP包,然后编写一下代码即可成功动态加载XAP包。

public partial class MainPage : UserControl
{
public MainPage()
{
InitializeComponent();
}

private void button1_Click(object sender, RoutedEventArgs e)
{
//1 •使用WebClient下载SLRandarHitTest.xap文件,进行异步读取。
WebClient Appclient = new WebClient();
Appclient.OpenReadAsync(
new Uri("SLRandarHitTest.xap", UriKind.Relative));
Appclient.OpenReadCompleted
+= new OpenReadCompletedEventHandler(Appclient_OpenReadCompleted);

}

void Appclient_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
{
CreateXAPResource(
"SLRandar.dll","SLRandar.MainPage",e.Result);
}
/// <summary>
/// 创建XAP包的反射实例并且加装到Canvas中
/// </summary>
/// <param name="dllStr">XAP包中的编译完成的运行代码的DLL文件</param>
/// <param name="mainStr">需要实例化的启动页面</param>
/// <param name="resultStream">使用WebClient下载到的数据流</param>
private void CreateXAPResource(string dllStr,string mainStr,Stream resultStream)
{
//2 •
//3 •获取其他包提供的资源流信息
StreamResourceInfo streamResourceInfo = Application.GetResourceStream(new StreamResourceInfo(resultStream as Stream, null), new Uri(dllStr, UriKind.RelativeOrAbsolute));
//4 •对Stream进行反射
AssemblyPart assemblyPart = new AssemblyPart();
Assembly assembly
= assemblyPart.Load(streamResourceInfo.Stream);
//5 •(创建实例
var uc = (UserControl)assembly.CreateInstance(mainStr);
lRoot.Children.Clear();
lRoot.Children.Add(uc);
}

}

        本实例采用VS2010+Silverlight 4.0编写,如需源码点击 SLoadXAP.zip 下载。

posted @ 2011-03-29 16:02  程兴亮  阅读(3504)  评论(16编辑  收藏