默认情况下,如果SL项目引用了一些其它程序集(即通俗意义上的dll文件),在编译打包时,这些dll会全部打包到一个xap文件里,随着引用的dll文件越来越多,xap文件会越来越大。
这还不是最严重的问题,如果确实需要使用这些dll,大就大吧,要用它容量肯定就会增加。但是如果多个SL项目都要引用相同的程序集时,这些dll会重复打包进每个xap文件,用户在加载多个xap时,实际上是重复下载了这部分dll文件,带宽使用率太低。
为了改善这种情况,SL引用了"应用程序库缓存"的概念,在vs2010的SL项目中,打开SL项目的属性页,会看到一个选项:“通过使用应用程序库缓存减少XAP大小(R)”

勾上这个后,查看一下最终的ClientBin目录,会发现一些项目引用的其它程序集,已经分离出来变成了zip文件

再稍微唠叨一下:上图中的MySLApp.xap在下载时,怎么知道会去加载System.Runtime.Serialization.Json.zip呢?
揭密:随便找个解压软件(比如WinRAR,WinZIP,7-ZIP之类),用它打开MySLApp.xap文件,把里面的AppManifest.xaml解压出来,用记事本打开,会看到类似以下内容:
<Deployment xmlns="http://schemas.microsoft.com/client/2007/deployment" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" EntryPointAssembly="MySLApp" EntryPointType="MySLApp.App" RuntimeVersion="4.0.50826.0"> |
<Deployment.Parts> |
<AssemblyPart x:Name="MySLApp" Source="MySLApp.dll" /> |
</Deployment.Parts> |
<Deployment.ExternalParts> |
<ExtensionPart Source="System.Runtime.Serialization.Json.zip" /> |
</Deployment.ExternalParts> |
</Deployment> |
这里的 <ExtensionPart Source="System.Xml.Serialization.zip" />就通知运行时加载同目录下的System.Xml.Serialization.zip,首次加载时会下载所有xap以及相关的zip文件,下载浏览页面时,如果缓存没有清空掉,zip文件将直接从缓存中读取,不会重复下载。
但是有一个问题,只有强命名的程序集可以这么做,如果是用户自己开发的类库,默认情况下就算你勾选了这个选项,最终还是会将dll一起打包进xap文件,如何也让自己开发的SL类库使用缓存呢?
步骤1:先为自己的SL类库程序集(使用强名称)签名
这一步可以借助vs2010完成,见下图

然后重新编译
步骤2:创建xml映射文件
打开SL类库的编译输出目录(默认为bin\Debug目录),创建一个xml文件,文件名规则如下
比如类库输出的dll文件名为MyTools.dll,则这个xml文件必须是MyTools.extmap.xml,即 "dll文件主名+.extmap.xml"(且这个文件必须跟dll文件处于同一级目录),内容如下:
- <?xml version="1.0"?>
- <manifest xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xmlns:xsd="http://www.w3.org/2001/XMLSchema">
- <assembly>
- <name>MyTools</name>
- <version>1.0.0.0</version>
- <publickeytoken>c934ea1d360b6e15</publickeytoken>
- <relpath>MyTools.dll</relpath>
- <extension downloadUri="MyTools.zip" />
- </assembly>
- </manifest>



步骤3:SL项目引用这个dll(或SL类库),并正确勾选"通过使用应用程序库缓存减少XAP大小(R)”即可
最终在ClientBin目录下,会看到类似下面的输出:

可以看到VS已经自动将MyTools.dll打包成了zip文件,然后查看一下MySLApp.xap中的AppManifest.xaml内容
- <Deployment xmlns="http://schemas.microsoft.com/client/2007/deployment" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" EntryPointAssembly="MySLApp" EntryPointType="MySLApp.App" RuntimeVersion="4.0.50826.0">
- <Deployment.Parts>
- <AssemblyPart x:Name="MySLApp" Source="MySLApp.dll" />
- </Deployment.Parts>
- <Deployment.ExternalParts>
- <ExtensionPart Source="MyTools.zip" />
- <ExtensionPart Source="System.Runtime.Serialization.Json.zip" />
- <ExtensionPart Source="System.Xml.Serialization.zip" />
- </Deployment.ExternalParts>
- </Deployment>
注意<ExtensionPart Source="MyTools.zip" />,vs也自动为我们添加了这一行。
注:应用程序缓存不适用于OOB方式