Silverlight怎样加载xap中的各个程序集
假设有一个程序集资源:http://elvis.egyee.com/myassembly.dll
如果你想在其他地方如果Silverlight中使用,只要用WebClient下载这个文件,然后:
AssemblyPart part = new AssemblyPart();
Assembly ass = part.Load("下载的Stream");
但是如果你有几个dll文件,想要打成一个.zip包一次性下载下来,怎样将zip中的各个程序集加载呢?
你可能会说用ILMerge之类的工具,将程序集合并,但是目前程序集合并的工具基本上不能处理WPF/Silverlight的程序集。
怎么办呢?
这时候我们突然想,Silverlight本身的程序集不是打成一个压缩包下载的吗,我们可不可以借鉴一下,于是沿着这个思路我们找到了方法。
1,构造一个名为AppManifest.xaml的XMl文件,文件格式如下:
<Deployment xmlns="http://schemas.microsoft.com/client/2007/deployment" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" EntryPointAssembly="Egyee.Client" EntryPointType="Egyee.Client.App" RuntimeVersion="4.0.50826.0">
<Deployment.Parts>
<AssemblyPart x:Name="Egyee.Client" Source="Egyee.Client.dll" />
<AssemblyPart x:Name="Egyee.Client.Common" Source="Egyee.Client.Common.dll" />
<AssemblyPart x:Name="Egyee.Client.Hosting" Source="Egyee.Client.Hosting.dll" />
<AssemblyPart x:Name="Egyee.Client.ServiceClient" Source="Egyee.Client.ServiceClient.dll" />
<AssemblyPart x:Name="System.ComponentModel.Composition" Source="System.ComponentModel.Composition.dll" />
<AssemblyPart x:Name="System.ComponentModel.Composition.Initialization" Source="System.ComponentModel.Composition.Initialization.dll" />
<AssemblyPart x:Name="System.ComponentModel.DataAnnotations" Source="System.ComponentModel.DataAnnotations.dll" />
<AssemblyPart x:Name="System.Windows.Controls" Source="System.Windows.Controls.dll" />
<AssemblyPart x:Name="System.Xml.Linq" Source="System.Xml.Linq.dll" />
</Deployment.Parts>
</Deployment>
2,学着SL的做法,将一些dll和这个AppMainfest.xaml文件打成一个zip包,或者也改名成.xap包
3,在SL中用WebClient下载下来,使用如下的方法:
private static IEnumerable<AssemblyPart> GetDeploymentParts(StreamResourceInfo packageStreamInfo)
{
Uri manifestUri = new Uri("AppManifest.xaml", UriKind.Relative);
StreamResourceInfo manifestStreamInfo = Application.GetResourceStream(xapStreamInfo, manifestUri);
List<AssemblyPart> assemblyParts = new List<AssemblyPart>();
if (manifestStreamInfo != null)
{
Stream manifestStream = manifestStreamInfo.Stream;//或者到XML流
using (XmlReader reader = XmlReader.Create(manifestStream))
{
if (reader.ReadToFollowing("AssemblyPart"))
{
do
{
string source = reader.GetAttribute("Source");
if (source != null)
{
//找到各个dll的文件名
assemblyParts.Add(new AssemblyPart() { Source = source });
}
}
while (reader.ReadToNextSibling("AssemblyPart"));
}
}
}
return assemblyParts;
}
4,再使用如下方法调用:
public static IEnumerable<Assembly> LoadPackagedAssemblies(Stream packageStream)
{
List<Assembly> assemblies = new List<Assembly>();
StreamResourceInfo packageStreamInfo = new StreamResourceInfo(packageStream, null);
IEnumerable<AssemblyPart> parts = GetDeploymentParts(packageStreamInfo);
foreach (AssemblyPart ap in parts)
{
StreamResourceInfo sri = Application.GetResourceStream(
packageStreamInfo, new Uri(ap.Source, UriKind.Relative));
assemblies.Add(ap.Load(sri.Stream));
}
packageStream.Close();
return assemblies;
}