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 下载。