最近看书比较多,正好对过去几年的软件开发做个总结。写这个的初衷只是为了简单的做一些记录。

前言

复杂的应用程序总是面临很多的页面之间的数据交互,怎样创建松耦合的程序一直是多数工程师所思考的问题。诸如依赖注入,PubSub模式,MVVM等概念,都致力于帮助我们创建更加松耦合易于维护的程序,也有不少框架实现了这些功能,Prism就是其中一个。

Prism是微软的实践和模式小组写的一套框架,包含了常用的依赖注入方式(Autofac,Mef,Ninject,StructureMap,Unity),MVVM,数据校验,基于PubSub的消息模型,导航,插件管理等等功能,能够帮助我们创建伸缩性好,耦合度低的程序。下面我们开始尝试从一个普通的WPF程序开始,将它改造成一个使用Prism框架的程序。

开发环境

Windows 10 10586

Visual Studio 2015

.Net Framework 4.6.1

Prism 6

新建PrismSample项目

因为希望能够进行插件式的开发,所以IoC容器选择了MEF。新建一个WPF项目,命名为PrismSample。然后我们需要从nuget导入三个包:

我们先将Prism.Core,Prism.Mef,Prism.MVVM添加进来。添加完之后,我们需要将我们的MainWindow删除掉,因为我们希望实现自己的主页面。当然,在App.xaml文件中也要做修改:

<Application x:Class="PrismSample.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:PrismSample">
<Application.Resources> </Application.Resources>
</Application>

这时候,我们的项目是无法正常启动的。接下来我们要新建一个Shell页面,作为我们的主页面。

新建PrismSample.Infrastructure.Abstract

新建一个类库项目,将其命名为PrismSample.Infrastructure.Abstract,并建立如下结构的文件:

为了创建IViewModel接口和ViewModelBase的抽象类,我们需要先从nuget中引入Prism.Mvvm。当我们添加完后,实现文件内容如下:

namespace PrismSample.Infrastructure.Abstract.Presentation.Interface
{
public interface IViewModel
{
IView View { get; }
}
} using Microsoft.Practices.Prism.Mvvm;
using PrismSample.Infrastructure.Abstract.Presentation.Interface; namespace PrismSample.Infrastructure.Abstract.Presentation.AbstractClass
{
public abstract class ViewModelBase : BindableBase, IViewModel
{
public IView View { get; protected set; }
}
}

在PrismSample中实现内容

新建Shell页面

添加页面Shell:

<Window x:Class="PrismSample.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:local="clr-namespace:PrismSample"
mc:Ignorable="d"
Title="Shell" Height="300" Width="300">
<Grid>
<TextBlock Text="{Binding Text}" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Grid>
</Window> using Microsoft.Practices.Prism.Mvvm;
using System.ComponentModel.Composition;
using System.Windows; namespace PrismSample
{
[Export("ShellView", typeof(IView))]
public partial class Shell : Window, IView
{
public Shell()
{
InitializeComponent();
}
}
}

新建Shell的ViewModel

using PrismSample.Infrastructure.Abstract.Presentation.Interface;
using Microsoft.Practices.Prism.Mvvm;
using System.ComponentModel.Composition;
using PrismSample.Infrastructure.Abstract.Presentation.AbstractClass; namespace PrismSample
{
[Export("ShellViewModel",typeof(IViewModel))]
public class ShellViewModel : ViewModelBase
{
private string _text; public string Text
{
get { return _text; }
set { SetProperty(ref _text, value); }
} [ImportingConstructor]
public ShellViewModel([Import("ShellView", typeof(IView))] IView view)
{
this.View = view;
this._text = "Hello World";
this.View.DataContext = this;
}
}
}

新建Bootstrapper类

using Prism.Mef;
using PrismSample.Infrastructure.Abstract.Presentation.Interface;
using System.ComponentModel.Composition.Hosting;
using System.Windows; namespace PrismSample
{
public class Bootstrapper : MefBootstrapper
{
protected override DependencyObject CreateShell()
{
IViewModel shellViewModel = this.Container.GetExportedValue<IViewModel>("ShellViewModel");
return shellViewModel.View as DependencyObject;
} protected override void InitializeShell()
{
Application.Current.MainWindow = (Shell)this.Shell;
Application.Current.MainWindow.Show();
} protected override void ConfigureAggregateCatalog()
{
base.ConfigureAggregateCatalog(); //加载自己
this.AggregateCatalog.Catalogs.Add(new AssemblyCatalog(this.GetType().Assembly));
}
}
}

修改App.xaml.cs文件

using System.Windows;

namespace PrismSample
{
public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
Bootstrapper bootstrapper = new Bootstrapper();
bootstrapper.Run();
}
}
}

最后的文件结构和运行结果



小结

本篇通过一个简单的应用建立了一个基于Prism的包含Ioc和Mvvvm的小程序,虽然是个小程序,但包含了Prism的精髓--组合。

源码下载

参考信息

Silverlight中利用MEF进行模块注入时注入错误问题分析

【翻译】WPF应用程序模块化开发快速入门(使用Prism框架)【上】

Prism6下的MEF:第一个Hello World的更多相关文章

  1. Prism6下的MEF:基于微软企业库的Cache

    通常,应用程序可以将那些频繁访问的数据,以及那些需要大量处理时间来创建的数据存储在内存中,从而提高性能.基于微软的企业库,我们的快速创建一个缓存的实现. 新建PrismSample.Infrastru ...

  2. Prism6下的MEF:添加Logger

    上篇已经简单的构建了一个Prism的程序,现在我们需要添加一个Logger,Prism本身自带一个功能简单的TextLogger,但是我们希望能用.Net常用的Log4net.所以我们需要重载掉Boo ...

  3. Swift技术之如何在iOS 8下使用Swift设计一个自定义的输入法 (主要是NSLayoutConstraint 的使用)

    当前位置: > Swift新手入门 > Swift技术之如何在iOS 8下使用Swift设计一个自定义的输入法 时间:2014-09-10 16:49来源:未知 作者:啊成 举报 点击:5 ...

  4. Eclipse 下如何引用另一个项目的Java文件

    有关联的2个项目,有些类是相同的.例如实体类. 如果你采用 Ctrl + C & Ctrl + V 的方式,以后再有改动,2个项目就都需要改动. 怎样才能只改动一个呢? 答案就是,在一个项目( ...

  5. Eclipse 下如何引用另一个项目的资源文件

    为什么要这么做?可参考:Eclipse 下如何引用另一个项目的Java文件 下面直接说下步骤:(项目A 引用 项目B的资源文件) 1.右键 项目A,点击菜单 Properties 2.在弹出的框中,点 ...

  6. Qt ------ window下工程项目打包成一个exe程序

    最近,在学习QT5的过程中,想尝试着把自己写的工程程序给打包发布出来,在任何一台windows系统都能运行,这样就不会限于电脑需不需要安装QT安装包了. 首先,先介绍自己使用的环境.我使用的QT版本是 ...

  7. 在Linux下,如何分析一个程序达到性能瓶颈的原因

    0.在Linux下,如何分析一个程序达到性能瓶颈的原因,请分别从CPU.内存.IO.网络的角度判断是谁导致的瓶颈?注意现在的机器CPU是多核 1.用sar -n DEV 1 10 2.用iotop命令 ...

  8. 【小程序】微信小程序打开其他小程序(打开同一主体公众号下关联的另一个小程序)

    微信小程序打开其他小程序(打开同一公众号下关联的另一个小程序) 注:只有同一(主体)公众号下的关联的小程序之间才可相互跳转  wx.navigateToMiniProgram(OBJECT) wx.n ...

  9. PyCharm在同一个包(package)下,如何把一个.py文件导入另外一个.py文件下

    PyCharm在同一个包(package)下,如何把一个.py文件导入另外一个.py文件下 在同一个包下只需要用import 掉以后就可以找到模块所在的位置,但是如果不在同一个包下,在需要返回父级调用 ...

随机推荐

  1. 【BZOJ1044】[HAOI2008]木棍分割

    [BZOJ1044][HAOI2008]木棍分割 题面 bzoj 洛谷 题解 第一问显然可以二分出来的. 第二问: 设\(dp[i][j]\)表示前\(i\)个,切了\(j\)组的方案数 发现每次转移 ...

  2. 【mysql】排序方法

    查询各科成绩前三名的记录,不考虑并列的情况: select a.course_id as 课程ID, a.score as 成绩, count(a.course_id) as 排名 from scor ...

  3. 5469: [FJOI2018]领导集团问题

    5469: [FJOI2018]领导集团问题 链接 题意: 要求在一棵树内选一个子集,满足子集内的任意两个点u,v,如果u是v的祖先,那么u的权值小于等于v. 分析: dp[u][i]表示在u的子树内 ...

  4. code first 创建数据库,add-migration update-database

    第一步: 第二步:

  5. JavaScript流程控制及函数

    1 流程控制 1.1 条件语句 分支结构 单向分支 if (条件表达式) { code...} 双向分支 if (条件表达式){    } else {    } <!DOCTYPE html& ...

  6. 关于IPointerEnterHandler和IpointerExitHandler的简单说明

    自己在学习UGUI背包系统时用到了,而且遇到一些问题,所以在这里写一下这两个接口的简单说明. 继承IPointerEnterHandler和IpointerExitHandler这两个接口后可以实现两 ...

  7. shell中与运算 cut切分行 if while综合在一起的一个例子

    前言: 公司要统计 treasury库hive表磁盘空间,写了个脚本,如下: 查询hive仓库表占用hdfs文件大小: hadoop fs -du -h  /user/hive/warehouse/t ...

  8. 【CodeForces-1041C】Coffee Break(二分解决关于set,pair,upper_bound用法)

    //题意:一个的工作时间是m分钟. // 在特定的时间和咖啡 n a1,a2....an,, ai代表的是每个咖啡要在一天中对应的时间点喝掉 // 每一次喝咖啡的时间为1分钟 // 必须在一天中的ai ...

  9. bootstrape3 模态

    version 2 的模态 不能在 version 3 上面用. http://schy-hqh.iteye.com/blog/1995690

  10. resize2fs命令详解

    基础命令学习目录首页 原文链接:http://blog.51cto.com/woyaoxuelinux/1870299   resize2fs:调整ext文件系统的空间大小  搭配逻辑卷lv使用方法: ...