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框架)【上】


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM