Prism学习笔记(一) 从Hello World开始

就像以往的入门,从伟大的Hello World开始吧。其实网上已经有不少Prism的入门图例,但是就只是很简单的说了一下操作过程,为什么要这么写代码和背后原理写的很少,看了以后有点知其然而不知其所以然的感觉。

不要小看Hello World这个简单的程序,他其实已经包含了不少重要的概念,比如容器,依赖注入,为什么要Bootstrapper这个类,Shell是干什么用的,我将会在我的笔记里面一条条的详细介绍他们。

先新建一个Silverlight Application,命名为MyPrism。

 建好后可以看见一个App.xaml和MainPage.xaml文件,App.xaml的作用就相当与.Net web程序中的Global.asax文件,其中包括了Application_Startup方法.

private void Application_Startup(object sender, StartupEventArgs e)
{
this.RootVisual = new MainPage();
}

这个方法实现的是整个程序的入口,Application.RootVisual 的属性是获取或设置主要应用程序用户界面,只能从代码设置 RootVisual 属性的值一次,尽管可以通过任意次数获取其值。这里是把MainPage.xaml作为了初始页面。

我们要修改这部分用我们的自己Bootstrapper来替换他

private void Application_Startup(object sender, StartupEventArgs e)
{
Bootstrapper bootstrapper = new Bootstrapper();
bootstrapper.Run();

}

程序会提示找不到Bootstrapper类,我们后面会创建他。

首先要添加Prism的assemblies:

  • Microsoft.Practices.Prism.dll
  • Microsoft.Practices.Prism.UnityExtensions.dll
  • Microsoft.Practices.ServiceLocation.dll
  • Microsoft.Practices.Unity.Silverlight.dll

记住在安装完Prism以后,进入Prism4的文件夹,双击执行RegisterPrismBinaries.bat文件,就能把所有的Prism assemblies添加入本地类库,你就能在add reference的.Net tab下找到他们了。具体每个作用,我这里就偷懒贴一端官方原文吧

Microsoft.Practices.Prism.dll. This assembly contains the implementation of the Prism Library core components, such as modularity, logging services, communication services, and definitions for several core interfaces. It also contains the implementation of the Prism Library components that target Silverlight applications, including commands, regions, and events.

Microsoft.Practices.Prism.UnityExtensions.dll. This assembly contains base and utility classes you can reuse in applications built with the Prism Library that consume the Unity Application Block. For example, it contains a bootstrapper base class, the UnityBootstrapperclass, that creates and configures a Unity container with default Prism Library services when the application starts.

Microsoft.Practices.Unity.Silverlight.dll. This assembly enables you to use the Unity Application Block in your application. By default, applications built using Prism use the Unity Application Block. However, developers who prefer to use different container implementations can build adapters for them using the provided extensibility points in the Prism Library.

Microsoft.Practices.ServiceLocation.dll. This assembly contains the Common Service Locator interface used by Prism to provide an abstraction over Inversion of Control (IoC) containers and service locators; therefore, you can change the container implementation with ease.

在创建Bootstrapper之前,先重命名MainPage.xaml为Shell.xaml,方法如下:

Shell.xaml文件的作用:

Prism的理念是用Shell页面做主显示页面,将其划分成不同的区域 Region,然后把其他写好的module嵌入Shell页面中对应的Region,最终展现给用户。

修改Shell.xaml文件内容为 

<UserControl x:Class="MyPrism.Shell"
xmlns
="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x
="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d
="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc
="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:Regions
="http://www.codeplex.com/prism"
mc:Ignorable
="d"
d:DesignHeight
="300" d:DesignWidth="400">

<ItemsControl Name="MainRegion" Regions:RegionManager.RegionName="MainRegion"/>

</UserControl>

 

关键就是这句 <ItemsControl Name="MainRegion" Regions:RegionManager.RegionName="MainRegion"/> 表示Shell中包含着一个名为“MainRegion”的Region。

xmlns:Regions="http://www.codeplex.com/prism"
用来引用Prism assembly.

接下来我们创建展示页面内容的module,add new project, 选择Silverlight Class Library, 命名为HelloWorldModule.

 新建一个Views文件夹,在这个歌文件夹下添加一个Silverlight User Control文件HelloWorldView.xaml

HelloWorldView.xaml包含我们最终要显示的内容,在其中添加一个TextBlock控件,显示Hello World内容。

<UserControl x:Class="HelloWorldModule.Views.HelloWorldView"
xmlns
="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x
="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d
="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc
="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable
="d"
d:DesignHeight
="300" d:DesignWidth="400">

<Grid x:Name="LayoutRoot" Background="White">
<TextBlock Text="Hello World" Foreground="Green" HorizontalAlignment="Center" VerticalAlignment="Center" FontFamily="Calibri" FontSize="24" FontWeight="Bold"></TextBlock>
</Grid>
</UserControl>


接下来重命名Class.cs为HelloWorldModule.cs

还记得我们在前面建立的Shell.xaml文件么?HelloWorldModule.cs将会把HelloWorldView.xaml绑定到Shell中的MainRegion。下面是HelloWorldModule.cs代码,由于这里引用了Microsoft.Practices.Prism.Modularity和Microsoft.Practices.Prism.Regions,所以要在reference中添加Microsoft.Practices.Prism。

using Microsoft.Practices.Prism.Modularity;
using Microsoft.Practices.Prism.Regions;

namespace HelloWorldModule
{
public class HelloWorldModule: IModule
{
private readonly IRegionManager regionManager;

public HelloWorldModule(IRegionManager regionManager)
{
this.regionManager = regionManager;
}

public void Initialize()
{
regionManager.RegisterViewWithRegion("MainRegion", typeof(Views.HelloWorldView));
}
}
}

这里使用了依赖注入的概念,依赖注入又被称为反转注入IOC,“使得对象只依赖IOC容器,不再相互依赖,而是在对象创建时,由IOC容器将其依赖的对象注入Inject其体内,故又称依赖注入依赖注射模式”,笔者第一次看到这段定义的时候也是莫名其妙,后来才发现其实依赖注入简单的很,网上文章很多,这里有一个链接http://www.cnblogs.com/xingyukun/archive/2007/10/20/931331.html 讲的还不错,有兴趣可以看看。

HelloWorldModule类继承了IModule interface,只有这样才可以被添加入容器的Module Collection中。

在HelloWorldModule类中,定义类的构造函数时,注入了IRegionManager regionManager这个对象,也就是说HelloWorldModule不会创建自己的IRegionManager对象,他将接受容器给他的IRegionManager对象。我会在最后的介绍BootStrapper中再提到这点。

记得在Shell.xaml中我们添加的<ItemsControl Name="MainRegion" Regions:RegionManager.RegionName="MainRegion"/>控件么Initialize()将会把HelloWorldView注册到regionManager中的MainRegion。

这是怎么实现的呢,我们来进入最后一项工作创建Bootstrapper类了。回到MyPrism中新建一个Bootstrapper.cs文件,将其代码修改如下:

using System;
using System.Windows;
using Microsoft.Practices.Prism.Modularity;
using Microsoft.Practices.Prism.UnityExtensions;
using Microsoft.Practices.Unity;

namespace MyPrism
{
public class Bootstrapper : UnityBootstrapper
{
protected override DependencyObject CreateShell()
{
return Container.Resolve<Shell>();
}

protected override void InitializeShell()
{
base.InitializeShell();
Application.Current.RootVisual = (UIElement)this.Shell;
}

protected override void ConfigureModuleCatalog()
{
base.ConfigureModuleCatalog();

ModuleCatalog moduleCatalog = (ModuleCatalog)this.ModuleCatalog;
moduleCatalog.AddModule(typeof(HelloWorldModule.HelloWorldModule));
}


}
}

Bootstrapper类将我们之前创建的Shell,HelloWorldModule整合在一起。

这里有三个方法,按执行次序来排是ConfigureModuleCatalog,CreateShell 和InitializeShell:

首先ConfigureModuleCatalog()中将HelloWorldModule添加入moduleCatalog,这个moduleCatalog将会管理所有的modules.

接着CreateShell() 产生了一个Shell instance,将作为我们的主页面。

最后InitializeShell()将这个Shell instance赋值给 Application.Current.RootVisual,最终在页面展示出来。(在本文的最开始我们修改了App.xaml.cs文件,将 Application.Current.RootVisual赋值工作移到这里来完成)。

初学者可能不太能理解Container.Resolve<Shell>();的用法,这里有篇文章写的很清楚了,可以看看 http://www.cnblogs.com/inrie/archive/2008/04/18/1159002.html

其实Container.Resolve<Shell>();就是返回一个Shell的instance,只不过是用Container来控制,一般来说在使用Resolve获得instance之前先要使用Container.RegisterType来注册类,如果没注册,就单纯的返回一个实例。所有在这里你也可以直接用new:

        protected override DependencyObject CreateShell()
{
return new Shell();
}

我们这个Shell比较简单,单纯的就一个控件,使用Container好处在于,但如果遇到比较复杂的Shell,其引用依赖于其他类,Resolve可以自动帮你把其他类都创建好,返回给你一个实例,用户不用管后台那些类的关系,谁要先建,谁引用谁,这些麻烦事情Container都帮你搞定。

说到这里我们也大功告成了。按一下F5键,将会得到下面的结果:

 

这是一个Prism的最基本的应用,里面包含其主要的思想,后面我们将讨论MVVM模式。

注:我的写作风格可能会令读者不太适应,大多数正规的教程一般都会先写原理框架,后写实际应用实例,实例配和原理。不过我不太喜欢这样,经常会都会刚开始的时候原理看的云里雾里,一知半解,很容易有疲惫感。等看到后面的实际应用时,又不知道要和前面哪段原理结合,效率很低。我觉得还是理论配合实践,把理论的东西分散到具体的应用中去,先实践,遇到障碍了再做原理分析。这样入手比较有成就感,不太容易被一堆概念吓倒。不知道效果如何。。。

源代码:https://files.cnblogs.com/mindflying/MyPrism.zip

 

posted @ 2011-10-18 00:23  FlyingSheep  阅读(2107)  评论(5编辑  收藏  举报