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

推荐订阅源

Engineering at Meta
Engineering at Meta
博客园_首页
H
Help Net Security
WordPress大学
WordPress大学
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
罗磊的独立博客
博客园 - 三生石上(FineUI控件)
B
Blog
I
InfoQ
SecWiki News
SecWiki News
T
Tailwind CSS Blog
Spread Privacy
Spread Privacy
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
V
Vulnerabilities – Threatpost
N
Netflix TechBlog - Medium
P
Palo Alto Networks Blog
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
Vercel News
Vercel News
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
K
Kaspersky official blog
M
MIT News - Artificial intelligence
S
Schneier on Security
T
Threat Research - Cisco Blogs
F
Fortinet All Blogs
Cyberwarzone
Cyberwarzone
Scott Helme
Scott Helme
aimingoo的专栏
aimingoo的专栏
Martin Fowler
Martin Fowler
MyScale Blog
MyScale Blog
The Cloudflare Blog
Recent Announcements
Recent Announcements
Security Latest
Security Latest
G
GRAHAM CLULEY
IT之家
IT之家
Y
Y Combinator Blog
The Last Watchdog
The Last Watchdog
腾讯CDC
Google DeepMind News
Google DeepMind News
V
V2EX
S
Securelist
TaoSecurity Blog
TaoSecurity Blog
B
Blog RSS Feed
S
SegmentFault 最新的问题
博客园 - 叶小钗
P
Proofpoint News Feed
云风的 BLOG
云风的 BLOG
Project Zero
Project Zero
G
Google Developers Blog
Google DeepMind News
Google DeepMind News
F
Full Disclosure

博客园 - 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.