2010-05-20 90 views
5

OnDemand Prism模块的加载应该在OOB scenerio中工作吗?如果是这样,我似乎无法使其工作。一切正在浏览器中正常工作,没有任何问题。具体地说I: 登记自己的模块中的代码:Prism OnDemand模块加载在OOB scenerio中工作吗?

protected override IModuleCatalog GetModuleCatalog() { 
     var catalog = new ModuleCatalog(); 
     Uri source; 

     if(Application.Current.IsRunningOutOfBrowser) { 
      source = IsolatedStorageSettings.ApplicationSettings[SOURCEURI] as Uri; 
     } 
     else { 
      var src = Application.Current.Host.Source.ToString(); 
      src = src.Substring(0, src.LastIndexOf('/') + 1); 
      source = new Uri(src); 
      IsolatedStorageSettings.ApplicationSettings[SOURCEURI] = source; 
      IsolatedStorageSettings.ApplicationSettings.Save(); 
     } 

     if(source != null) { 
      var mod2 = new ModuleInfo { InitializationMode = InitializationMode.OnDemand, 
          ModuleName = ModuleNames.mod2, 
          ModuleType = "mod2.Module, mod2.Directory, '1.0.0.0', Culture=neutral, PublicKeyToken=null"), 
          Ref = (new Uri(source, "mod2.xap")).AbsoluteUri }; 

      catalog.AddModule(mod2); 
     } 

// per Jeremy Likeness - did not help. 
     Application.Current.RootVisual = new Grid(); 

     return (catalog); 
    } 

用于待加载的模块由后面的请求:

mModuleManager.LoadModule(ModuleNames.mod2); 

,并等待到该装载的初始化过程中公布的一个事件的响应模块。

该模块似乎永远不会被加载,并且当应用程序在调试器下运行时,会出现一个消息框,指出Web服务器返回了“未找到”错误。我可以将该模块的请求url并输入到Firefox并下载模块,没有任何问题。

我一直没有找到任何可以实际操作的参考,但它似乎应该如此。我在这个主题上找到的最多的是blog entry by Jeremy Likeness,它涵盖了MEF中的加载模块,但是在这里应用他的知识并没有帮助。

服务器是本地主机(我听说它提到这可能会导致问题)。该服务器有一个clientaccesspolicy.xml文件 - 虽然我不指望这是必要的。 我使用的客户端堆栈和注册它应用在施工期间:

WebRequest.RegisterPrefix(Current.Host.Source.GetComponents(UriComponents.SchemeAndServer, UriFormat.UriEscaped), WebRequestCreator.ClientHttp); 

后续问题:

可以将所有xaps的安装以某种方式在客户端桌面 - 或者只在主应用程序XAP?以某种方式在appmanifest.xml中指定它们?

如果只安装了application.xap并且必须下载其余的xaps,是否值得使用这个工作?

+0

我也很想知道这个答案 - 我正在OOB工作,需要分解我的项目... – Rodney 2010-09-09 00:47:24

回答

1

一旦我工作在类似的情况。诀窍是将模块存储在独立存储中,并使用模块加载器在离线工作时从独立存储读取数据。

这是因为否则,您无法下载与Shell不同的.xap文件中的模块。

感谢, 达米安

0

如果你愿意来调整棱镜源和建立它自己有可能钩自定义模块装载机为棱镜。实际上,我可以很容易地实现这一点 - 在我们的应用程序中,我首先查看模块中的磁盘,如果找不到,我会回到从服务器通过支持第三方商业HTTP堆栈的方式加载它,客户证书。

为此,请下载Prism源代码,并找到Microsoft.Practices.Composite.Modularity.XapModuleTypeLoader类。该类使用另一个Prism类Microsoft.Practices.Composite.Modularity.FileDownloader来下载.xap内容;但它直接实例化,让你没有机会注入你自己的或任何东西。

所以 - 在XapModuleTypeLoader,我添加了一个静态属性来设置下载的类型:

public static Type DownloaderType { get; set; } 

然后我修改CreateDownloader()方法来使用上述类型优先于默认之一:

protected virtual IFileDownloader CreateDownloader() { 
    if (_downloader == null) { 
     if (DownloaderType == null) { 
      _downloader = new FileDownloader(); 
     } else { 
      _downloader = (IFileDownloader)Activator.CreateInstance(DownloaderType); 
     } 
    } 

    return _downloader; 
} 

当我的应用程序启动时,我的属性设置为我自己下载类型:

XapModuleTypeLoader.DownloaderType = typeof(LocalFileDownloader); 

Voila - 现在Prism调用你的代码来加载它的模块。

我可以给你发送我的LocalFileDownloader类以及它回退的类,如果你感兴趣的话,从网络载入.xap ...我怀疑如果你看Prism的FileDownloader类,你会看到它很简单。

关于您的其他问题,如果安装该应用程序的URL与您正在交谈的URL相同,或者您处于提升信任状态,则可能不需要clientaccesspolicy.xml文件。

.xaps绝对可以预先安装在客户端上,但这是一项工作。我们所做的是编写一个独立的.NET 2.0桌面应用程序的启动器应用程序。它下载主要的.xap加上某些模块*(根据需要检查更新和下载),然后根据需要卸载/重新安装应用程序,然后启动应用程序。最后两个是通过sllauncher.exe完成的,它是作为Silverlight的一部分安装的。这是一个很好的介绍:http://timheuer.com/blog/archive/2010/03/25/using-sllauncher-for-silent-install-silverlight-application.aspx

假设您在提升的信任下运行,还应该可以从SL客户端中预取模块.xaps,但在用户操作之前实际请求它们之前。您只需将它们放在我的文档某处的文件夹中,然后使用上述自定义模块加载方法将它们从那里拉出即可。

*在我们的例子中,我们的主要.xap是应用程序的2/3。我们的.xaps其余部分很小,因此我们随即下载它们,除了我们为第三方组件创建的一些.xaps外。我们不希望经常更新这些内容,所以我们会预先安装它们。