zoukankan      html  css  js  c++  java
  • Prism6下的MEF:第一个Hello World

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

    前言

    复杂的应用程序总是面临很多的页面之间的数据交互,怎样创建松耦合的程序一直是多数工程师所思考的问题。诸如依赖注入,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导入三个包:
    Image

    我们先将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,并建立如下结构的文件:
    Image

    为了创建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();
            }
        }
    }
    

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

    Image
    Image

    小结

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

    参考信息

    Silverlight中利用MEF进行模块注入时注入错误问题分析
    【翻译】WPF应用程序模块化开发快速入门(使用Prism框架)【上】

  • 相关阅读:
    Codeforces1101G (Zero XOR Subset)-less 【线性基】【贪心】
    Codeforces1101F Trucks and Cities 【滑动窗口】【区间DP】
    HDU4651 Partition 【多项式求逆】
    BZOJ2554 color 【概率DP】【期望DP】
    codeforces1101D GCD Counting 【树形DP】
    codechef EBAIT Election Bait【欧几里得算法】
    BZOJ2434 [NOI2011] 阿狸的打字机 【树链剖分】【线段树】【fail树】【AC自动机】
    codeforces1093G Multidimensional Queries 【线段树】
    BZOJ3277 串 【后缀数组】【二分答案】【主席树】
    AHOI2013 差异 【后缀数组】
  • 原文地址:https://www.cnblogs.com/youngytj/p/5670465.html
Copyright © 2011-2022 走看看