之前的章节中,从对一个计算器解决方案的重构,学会了Prism应用的基础知识。现在,我们再从一个新的Silverlight项目开始,继续Prism的学习。
看来今天运气有点背啊,我下载的Prism的版本是4.1的,它源码中的Silverlight部分是基于 Silverlight 5.0的。可惜,我当前系统中只安装了Silverlight 4.0 的 SDK。 郁闷中... 好不容易下载下来,一安装又提示要求安装 VS 2010 SP1。 要喷血了! 好吧,哥慢慢跟你耗着。
下载...安装.... (两个小时) .....
-_ -! .... 算了, 我睡觉的, 明天接着搞。
终于搞定了!开始今天的 Hello Silverlight:
首选,新建一个名叫SLDemoApplication的Silverlight应用程序。建好之后,需要删除掉里面的MainPage.xaml的自定义控件。
今天先让Prism跟Silverlight打个招呼,就用引用Shell了。直接创建两个Silverlight的应用程序: ModuleAProject, ModuleBProject, 直得注意的是,这里一定要选择创建Silverlight应用程序。如果选择Siverlight类库,那么他最后生成的是dll文件。这样的话,在稍后配置程序集清单的时候会有麻烦。
创建完成后,删除这两个程序集中的App.xaml和MainPage.xaml两项, 之后再添加一个类库:InterfaceProject。这里面用来记录上面创建的两个项目中需要实现的接口,在里面定义两个接口: ITextService和IUIService, 分别定义两个方法: string GetText(); UIElement GetUI()。 非常简单的两个接口。接着,在ModuleAProject中添加一个类,实现接口ITextService。在ModuleBProject中添加一个类,实现接口IUIService。代码如下:
1 public class TextService:ITextService
2 {
3 public string GetText()
4 {
5 return "Hello Silverlight!";
6 }
7 }
public class UIService : IUIService { ITextService textService; public UIService(ITextService textService) { this.textService = textService; } public UIElement GetUI() { return (new TextBox() { Text = textService.GetText(), VerticalAlignment = VerticalAlignment.Top, Width = 300 }); } }
非常简单,紧接着是最重要的一个步骤:在这两个模块里面,分别添加一个类,实现IModule接口,并在该类中,注册各自的类。代码如下:
1 public class TextServiceModule:IModule
2 {
3 IUnityContainer container;
4
5 public TextServiceModule(IUnityContainer container)
6 {
7 this.container = container;
8 }
9
10 public void Initialize()
11 {
12 container.RegisterType<ITextService, TextService>();
13 }
14 }
1 public class UIServiceModule:IModule
2 {
3 IUnityContainer container;
4
5 public UIServiceModule(IUnityContainer container)
6 {
7 this.container = container;
8 }
9
10 public void Initialize()
11 {
12 container.RegisterType<IUIService, UIService>();
13 }
14 }
两个模块定义好了, 接下来的事情,就是想办法在主程序中来调用了。在SLDemoApplication项目添加一个类,让其实现 IModule接口:代码如下:
1 public class MainModule:IModule
2 {
3 IUnityContainer container;
4
5 public MainModule(IUnityContainer container)
6 {
7 this.container = container;
8 }
9
10 public void Initialize()
11 {
12 IUIService ui = container.Resolve<IUIService>();
13
14 App.Current.RootVisual = ui.GetUI();
15 }
16 }
这一个类的作用是从Prism框架中,把已经注册好了的UIService取出来,获取一个UI控件给 Application的RootVisual。这样,这个控件就可以被加载到起始页中了。为了让上面的代码顺利执行,我们还需要做三件事:
1. 定义一个UnityBootstrapper类。 在这个自定义的类里实现从服务器加程序清单,该类需要添加到SLDemoApplication项目下。代码如下:
1 public class SLBootstrapper: UnityBootstrapper
2 {
3 protected override Microsoft.Practices.Prism.Modularity.IModuleCatalog CreateModuleCatalog()
4 {
5 return Microsoft.Practices.Prism.Modularity.ModuleCatalog.CreateFromXaml(
6 new Uri("modulecatalog.xaml", UriKind.Relative));
7 }
8
9 protected override DependencyObject CreateShell()
10 {
11 return null;
12 }
13 }
2. 配置程序集清单,如上面的代码中所示,SLBootstrapper将会从服务器上的modulecatalog.xaml文件中去取回程序集清单。所以,我们需要为他创建一个同名的文件。不过,这个文件是一个xml格式的文件。本解决方案中程序集的配置信息如下(ModuleType中还非要加上版本号,不加不跟你玩... ):
1 <?xml version="1.0" encoding="utf-8" ?>
2 <Modularity:ModuleCatalog
3 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
4 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
5 xmlns:sys="clr-namespace:System;assembly=mscorlib"
6 xmlns:Modularity="clr-namespace:Microsoft.Practices.Prism.Modularity;assembly=Microsoft.Practices.Prism">
7
8 <Modularity:ModuleInfo
9 Ref="ModuleAProject.xap"
10 ModuleName="TextServiceModule"
11 ModuleType="ModuleAProject.TextServiceModule, ModuleAProject, Version=1.0.0.0"/>
12
13 <Modularity:ModuleInfo
14 Ref="ModuleBProject.xap"
15 ModuleName="UIServiceModule"
16 ModuleType="ModuleBProject.UIServiceModule, ModuleBProject, Version=1.0.0.0">
17 <Modularity:ModuleInfo.DependsOn>
18 <sys:String>TextServiceModule</sys:String>
19 </Modularity:ModuleInfo.DependsOn>
20 </Modularity:ModuleInfo>
21
22 <Modularity:ModuleInfo
23 Ref="SLDemoApplication.xap"
24 ModuleName="MainModule"
25 ModuleType="SLDemoApplication.MainModule, SLDemoApplication, Version=1.0.0.0">
26 <Modularity:ModuleInfo.DependsOn>
27 <sys:String>UIServiceModule</sys:String>
28 </Modularity:ModuleInfo.DependsOn>
29 </Modularity:ModuleInfo>
30
31 </Modularity:ModuleCatalog>
3.运行启动器。我们知道,Silverlight的程序是从App.xaml开始启动的。启动时,会触发 Application_Startup 事件,默认情况下,会实例化MainPage对象,并将该对象赋给App的RootVisual属性。这样,MainPage就被发送到请求的客户端了。之前,我们删除了MainPage。 不过是否注意到了在 MainModule 类的 Initialize方法中我们也向当前的App的属性赋了一个值:UIService创建的 UI控件。 也就是说,当我们执行SLUnityBootstrapper 的时候,就会自动将程序集中创建好的UI控件加载客户端中。所以,就有了如下的代码:
1 private void Application_Startup(object sender, StartupEventArgs e)
2 {
3 SLBootstrapper boot = new SLBootstrapper();
4 boot.Run();
5 }
好了。程序完成,测试通过。 今天先让 Prism跟 Silverlight打个招呼。明天继续... ...
今天的源代码点击这里下载!