当您开发一个大型的Silverlight应用程序,将其分解为许多小组件,使原始XAP文件相对较小并根据需要从服务器端动态加载必要的DLL时,这是常识。
一种简单的方法是从运行时的程序中下载(从WebClient)程序中的dll到存储在System.Windows.Application.Current.Host.Source(通常)中的URL,使用Assembly对象和反射动态解析IL代码并检索DLL中的信息,创建它的实例并使用它的机制。但是在这个过程之后,这个Dll对于整个应用程序仍然是不可见的。
但这种方式似乎是“本地的和临时的”,现在我正在寻找一种可以从客户端动态加载DLL的'全局和永久'方式,将这个Dll添加到整个项目中(就像添加引用一样)这个项目在视觉工作室)。在加载之后,我希望应用程序可以使用新加载的Dll中的类或任何内容,就像使用最初加载的XAP中最初包含的DLL中的那些,在任何线程中使用它们,尽管仍然使用反射,我可以在任何线程中或在此加载后的任何地方或任何时间使用此DLL。
我在问这种延迟加载,我的意思是,实际加载,是否可以在.NET silverlight中实现,或者我该怎么做呢。
这对我来说相对困难,但对你来说可能相当容易。
提前多多感谢。
答案 0 :(得分:1)
我不是100%肯定这是您正在寻找的,但在Silverlight项目属性中,选中“使用应用程序库缓存减少XAP大小”。
这将在XAP加载时加载任何依赖库,但将它们保存在单独的zip中。从您构建的任何库都必须包含“libraryname.extmap.xml”文件。这是DevStudio的触发器,它应该将其捆绑为zip。文件的属性应选中“复制到输出目录”。内容应如下所示:
<?xml version="1.0" encoding="utf-8" ?>
<manifest xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<assembly>
<name>Common</name>
<version>1.0.0.0</version>
<publickeytoken>20f21d15449ebfc7</publickeytoken>
<relpath>Common.dll</relpath>
<extension downloadUri="Common.zip" />
</assembly>
</manifest>
答案 1 :(得分:1)
我这样做,将一个单独的类作为assemblyLibrary 创建一个webservice,它获取你想要启动的应用程序的标识符,并为你提供dll的Url集合, 检查你的库中是否已经有它们,如果没有下载并参考它们,这里有几个关键部分:
public static void LoadRefeferenceAssembly(string AssemblyCollectionName)
{
AssemblyDefinitionProviderClient alc = new AssemblyDefinitionProviderClient();
alc.getAssemblyListCompleted += alc_getAssemblyListCompleted;
alc.getAssemblyListAsync(AssemblyCollectionName);
}
static void alc_getAssemblyListCompleted(object sender, getAssemblyListCompletedEventArgs e)
{
if (e.Result == null || e.Error != null)
{
throw new ArgumentException("Assembly for cache error");
}
foreach (AssemblyDescription description in e.Result)
{
if (ReferencedAssemblies.Keys.Contains(description.name)) continue;
var ass = new ReferencedAssembly { Name = description.name, PercentLoaded = 0.0, Uri = new Uri(description.url, description.kind), State = ReferencedAssemblyStates.None };
if (description.isMainAssembly)
{
_currentMainAssembly = description.name;
ass.MainUIElementName = description.MainUIElementString;
}
ReferencedAssemblies.Add(description.name,ass);
}
beginCaching();
}
private static void beginCaching()
{
var tocache = Instance._ReferencedAssemblies.Values.FirstOrDefault(re => re.State == ReferencedAssemblyStates.None);
if (tocache == null)
{
changeContent();
return;
}
var wc = new WebClient();
//progress here
wc.OpenReadCompleted += (sender, e) =>
{
if (e.Result != null || e.Error == null)
{
AssemblyPart apart = new AssemblyPart();
tocache.AssemblyPart = apart.Load(e.Result);
tocache.State = ReferencedAssemblyStates.Done;
setStatus(tocache.Name + "Loaded");
}
else
{
tocache.Error = e.Error;
tocache.State = ReferencedAssemblyStates.Error;
setStatus(tocache.Name + "Error by Loading");
}
beginCaching();
};
wc.OpenReadAsync(tocache.Uri);
}