惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

T
Tenable Blog
Last Week in AI
Last Week in AI
P
Proofpoint News Feed
Engineering at Meta
Engineering at Meta
H
Help Net Security
F
Fortinet All Blogs
MyScale Blog
MyScale Blog
宝玉的分享
宝玉的分享
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
博客园 - 司徒正美
量子位
N
Netflix TechBlog - Medium
Apple Machine Learning Research
Apple Machine Learning Research
小众软件
小众软件
Recorded Future
Recorded Future
博客园 - 三生石上(FineUI控件)
Vercel News
Vercel News
aimingoo的专栏
aimingoo的专栏
I
InfoQ
Microsoft Security Blog
Microsoft Security Blog
Scott Helme
Scott Helme
The Last Watchdog
The Last Watchdog
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
IT之家
IT之家
AI
AI
WordPress大学
WordPress大学
Security Archives - TechRepublic
Security Archives - TechRepublic
Google Online Security Blog
Google Online Security Blog
U
Unit 42
V2EX - 技术
V2EX - 技术
MongoDB | Blog
MongoDB | Blog
Schneier on Security
Schneier on Security
博客园 - Franky
H
Heimdal Security Blog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Jina AI
Jina AI
W
WeLiveSecurity
P
Privacy & Cybersecurity Law Blog
Cloudbric
Cloudbric
B
Blog RSS Feed
N
News | PayPal Newsroom
S
Securelist
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
I
Intezer
Hacker News - Newest:
Hacker News - Newest: "LLM"
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
博客园_首页
罗磊的独立博客
H
Hackread – Cybersecurity News, Data Breaches, AI and More
雷峰网
雷峰网

博客园 - ocean

系统升级日记(4):如何快速的修改Infopath中的各种URL 系统升级日记(3)- 升级SharePoint解决方案和Infopath 系统升级日记(2)- 升级到SharePoint Server 2013 系统升级日记(1)- 升级到SQL Server 2012 一边是招人难,一边是找工作难,这个世界真的很有意思 SharePoint2010-CustomAction中的ContentTypeId属性已经消失了 office2010和sharepoint2010可以下载了? 一个子目录里放100W个文件及SQL Server File Stream中放100W文件,会怎么样? Teched2008 DEV301 ADO.NET Data Service资料下载 Teched 2008课程:ADO.NET Data Service & UC开发概览 我的基于Silverlight2的相册,也刚刚升级到了RTW了。 很囧,请大家不要给我留言 在MOSS中给增强型RTF字段增加按钮 在MOSS中实现自动上传图片 在Windows Server2008中运行MOSS不能启动Excel Service的问题 我也谈谈执行力 微软新技术巡展活动 将网站从WSS2.0升级到WSS3.0的心得 借宝地宣传一下:海洋工作室sps2007版用户系统正式运行!
Prism2.0之自定义ModuleCatalog(for Silverlight)
ocean · 2010-03-05 · via 博客园 - ocean

      今天比较高兴,因为网站的备案终于被审核通过了,我的网站很早之前就备过案,但是很奇怪两个月之前备案信息莫名其妙就消失了,结果在上次大检查中被迫关闭,重新备案路漫漫,经过两个月马拉松式的备案,今天备案信息终于通过,网站重新开通(http://www.oceanstudio.net/ ), 比较汗颜了,我的网站也没有更新什么东西。

      趁着高兴,写篇Blog吧,主要在于太长时间没写Blog了,现在也不知道写什么好,恰巧前段时间碰到有人问我,在Prism中,可否把模块信息放到xml文件中。这个自然没有问题,我们做一个自己的ModuleCatalog就好,不过我一直没有做,今天正好简单实现了一下,有兴趣的朋友可以参考。

  为什么要分模块,这个当然有很多好处,比如独立开发、独立测试,独立加载,而且模块之间没有直接引用,修改之后不会引起其他模块产生问题,总归好处多多。当我们做一个小型的Silverlight程序时,可以不用考虑Prism,直接做就好了,但是如果你做一个RIA,比如business application,那么可能会有上百个页面,不同的数据、表格等等,如果不分模块,那最后肯定就乱成一锅粥了。架构就是为了让我们的项目更加有条理,并且在变的越来越复杂时能够更好的控制,还能随时适应变化的要求。

      Prism2.0中,本身可以把模块的配置信息放置到XAML中,在自带的smaple中,我们可以看到如下代码:

 1 <Modularity:ModuleCatalog xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 2                xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 3                 xmlns:sys="clr-namespace:System;assembly=mscorlib"
 4                xmlns:Modularity="clr-namespace:Microsoft.Practices.Composite.Modularity;assembly=Microsoft.Practices.Composite">
 5     <Modularity:ModuleInfoGroup Ref="ModuleX.xap" InitializationMode="OnDemand">
 6         <Modularity:ModuleInfo ModuleName="ModuleX" ModuleType="ModuleX.ModuleX, ModuleX, Version=1.0.0.0" />
 7     </Modularity:ModuleInfoGroup>
 8     <Modularity:ModuleInfoGroup Ref="ModulesWY.xap" InitializationMode="WhenAvailable">
 9         <Modularity:ModuleInfo ModuleName="ModuleY" ModuleType="ModuleY.ModuleY, ModulesWY, Version=1.0.0.0">
10             <Modularity:ModuleInfo.DependsOn>
11                 <sys:String>ModuleW</sys:String>
12             </Modularity:ModuleInfo.DependsOn>
13         </Modularity:ModuleInfo>
14         <Modularity:ModuleInfo ModuleName="ModuleW" ModuleType="ModuleW.ModuleW, ModulesWY, Version=1.0.0.0">
15         </Modularity:ModuleInfo>
16     </Modularity:ModuleInfoGroup>
17     <!-- Module info without a group -->
18     <Modularity:ModuleInfo Ref="ModuleZ.xap" ModuleName="ModuleZ" ModuleType="ModuleZ.ModuleZ, ModuleZ, Version=1.0.0.0" />
19 </Modularity:ModuleCatalog>

     在Bootstrapper中,我们就可以如下调用:

代码

        protected override IModuleCatalog GetModuleCatalog()
        {
            
return
                ModuleCatalog.CreateFromXaml(
                    
new Uri("/RemoteModuleLoading;component/ModulesCatalog.xaml", UriKind.Relative));
        }

 如果我们要放在XML中,也很简单,声明如下的这么一个文件:

代码

<?xml version="1.0" encoding="utf-8" ?>
<Modules>
  
<Module name="LeftMenuModule" mode="WhenAvailable" type="SilverlightMonitorApplication.LeftMenuModule.LeftMenuModule, SilverlightMonitorApplication, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
  
<Module name="BottomMenuModule" mode="OnDemand" type="SilverlightMonitorApplication.BottomMenuModule.BottomMenuModule, SilverlightMonitorApplication, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null">
    
<Module.DependsOn>
      
<ModuleName>LeftMenuModule</ModuleName>
      
<ModuleName>Module1</ModuleName>
    
</Module.DependsOn>
  
</Module>
  
<Module name="Module1" mode="OnDemand" type="SilverlightMonitorApplication.Module1.Module1, SilverlightMonitorApplication, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null">
  
</Module>
  
<Module name="Module2" mode="OnDemand" type="SilverlightMonitorApplication.Module2.Module2, SilverlightMonitorApplication, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null">
  
</Module>
</Modules>

然后自己实现一个ModuleCatalog,我这里就命名为XmlModuleCatalog,这个XmlModuleCatalog当然要从ModuleCatalog继承下来。当然你也可以有更好的实现方式。我就提供个思路就好,代码我随手写的,论写代码,我是赶不上专职开发人员了。

代码

    public class XmlModuleCatalog : ModuleCatalog
    {
        
public XmlModuleCatalog(string xmlUri)
            : 
base()
        {
            
try
            {
                XElement doc 
= XElement.Load(xmlUri);

                var q 

= from x in doc.Descendants("Module")
                        select 
new ModuleInfo(x.Attribute("name").Value, x.Attribute("type").Value, (from c in x.Descendants("ModuleName")
                                                                                                     select c.Value).ToArray()
                                              ) { InitializationMode 
= x.Attribute("mode").Value.Equals("OnDemand"? InitializationMode.OnDemand : InitializationMode.WhenAvailable };foreach (ModuleInfo m in q)
                {
                    
this.AddModule(m);
                }
            }
            
catch
            {
                
throw new ArgumentException("XML file is not found or invalid!");
            }
        }
    }

      然后就可以在bootstrapper里面轻易调用

代码

        protected override IModuleCatalog  GetModuleCatalog()
        {
            
try
            {
                return
 new XmlModuleCatalog("ModuleInfo.xml");
            }
            
catch
            {
                
return null;
            }
        }

这里注意几点:

  1. XML文件的BuildAction为Content,不需要当做资源编译到dll中。
  2. 我没有去考虑每个模块在不同xap里面的情况,因为这种情况直接用xaml来描述就好了,没必要再自己重新做。
  3. Depends的问题,只要放在ModuleName里面就好了,我并没有去管ModuleName是否放在<Module.DependsOn>里面,当然主要是图省事。
  4. 我使用LINQ来实现的,这样比较省事一点,大家也可以用其它的方式来读取XML。

     这里说下模块按需下载的问题,如果模块需要按需下载,直接用XAML的形式就好了,这个Prism里面是自带的,不过考虑一般项目的模块不是特别多,而每个模块不是特别大,经常每个模块几十K,100多K,所以都打包在一起更加方便。当然如果模块过多或者过大,还是应该采用按需下载的方式比较好。

     在Prism中,模块的加载过程和那一大堆class啊,interface啊之间的关系,可以从下面两个图中来了解:

     上面两个图取自Prism的帮助文档中。 

      当然其实我定义这个xml文件,最初的初衷是想把module的view信息定义进去,让view也能根据配置文件动态加载。这个XmlModuleCatalog应该说是一个附属品。

      祝大家Happy.