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

posted on 2010-11-05 18:09  秦春林  阅读(1739)  评论(2编辑  收藏  举报

导航