LoginSignup
11
14

More than 5 years have passed since last update.

WPF で Prism と Autofac を使う

Posted at

WPF で Prism と Autofac を使います。

開発環境

Visual Studio Community 2017
.Net Framework 4.6.2
Prism.Autofac 6.3.0

準備

Visual Studio で 新規作成から WPF アプリを選択してプロジェクトを作成します。本記事では プロジェクト名を EduPrismWpfApp としています。

PrismTemplatePack

WPFに限らず Xamrin.Forms など Prism を使って開発をするときに、コントロールを専用のものにしたり、ViewModelLocator の設定など xaml に記述する必要がありますが、これらをテンプレート化してくれている Visual Studio の拡張機能として PrismTemplatePack がありますのでこれを入れておくと少し楽かもしれません。また、今回は使用していませんが Unity や Autofac 用のプロジェクトテンプレートも含まれています。

PrismTemplatePack
https://marketplace.visualstudio.com/items?itemName=BrianLagunas.PrismTemplatePack

パッケージの入手

『ソリューションの Nuget パッケージ管理』を開いて参照タブで Prism.Autofac と検索して一致したものをインストールしてください。 または『パッケージ マネージャーコントロール 』で以下のコマンドを入力してもインストールできます。

Install-Package Prism.Autofac -Version 6.3.0

Prism.Autofac
https://www.nuget.org/packages/Prism.Autofac

Shell の作成

Views フォルダを作成してその中に Shell.xaml をウインドウとして作成します。

Shell.xaml
<Window x:Class="EduPrismWpfApp.Views.Shell"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:prism="http://prismlibrary.com/"             
             prism:ViewModelLocator.AutoWireViewModel="True" 
        Title="EduPrismWpfApp">
    <Grid>

    </Grid>
</Window>

初期状態でプロジェクト直下に自動生成されている MainWindow.xaml は削除しておきます。

Bootstrapper の作成

プロジェクト直下に Bootstrapper.cs を作成して Bootstrapper クラスに AutofacBootstrapper を継承させます。ここではShell の登録と表示をおこなうための処理を追加します。

using Autofac;
using EduPrismWpfApp.Views;
using Prism.Autofac;
using System.Windows;

namespace EduPrismWpfApp
{
    class Bootstrapper : AutofacBootstrapper
    {
        protected override void ConfigureContainerBuilder(ContainerBuilder builder)
        {
            base.ConfigureContainerBuilder(builder);
            // Shell の登録
            builder.RegisterType<Shell>();
        }

        protected override DependencyObject CreateShell()
            => Container.Resolve<Shell>();

        protected override void InitializeShell()
        {
            base.InitializeShell();
            //  Shell を MainWindow に設定して表示する。
            Application.Current.MainWindow = (Shell)Shell;
            Application.Current.MainWindow.Show();
        }
    }
}

App.xaml と App.xaml.cs の修正

作成した Bootstrapper をアプリケーション起動時に呼び出すように App.xaml と App.xaml.cs を修正します。

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

    </Application.Resources>
</Application>
App.xaml.cs
using System.Windows;

namespace EduPrismWpfApp
{
    /// <summary>
    /// App.xaml の相互作用ロジック
    /// </summary>
    public partial class App : Application
    {
        private void Application_Startup(object sender, StartupEventArgs e) =>
            // Bootstrapperを起動
            new Bootstrapper().Run();
    }
}

この状態で実行すると作成した Shell が起動することが確認できると思います。

Module の登録

ソリューションに新しくプロジェクトを作成します。ソリューションエクスプローラでソリューションを右クリックして表示されるコンテクストメニューから「追加」→「新しいプロジェクト」を選択し『WPF ユーザーコントロールライブラリ』を選択してプロジェクトを作成します。本記事ではプロジェクト名を EduPrismWpfApp.Modules.SampleModule としています。普通のクラスライブラリではなく『WPF ユーザーコントロールライブラリ』で作成する理由としては参照設定など少し楽になるからです。作成されたプロジェクトに自動生成されているクラスまたはユーザーコントロールは削除しておきます。最初に作成したプロジェクトと同じように Nuget から Prism.Autofac のパッケージを追加しておいてください。

Model の作成

プロジェクトに Models フォルダを作成してその中に SampleMessageProvider.cs を作成します。今回はサンプルとして、 単純にメッセージ文字列をプロパティとして持っているだけのインターフェイスと、そのインターフェイスを継承したクラスを用意します。

SampleMessageProvider.cs
namespace EduPrismWpfApp.Modules.SampleModule.Models
{
    public interface ISampleMessageProvider
    {
        string Message { get; }
    }

    public class SampleMessageProvider : ISampleMessageProvider
    {
        public string Message => "Hello Prism App with Autofac";
    }
}

ViewModel の作成

プロジェクトに ViewModels フォルダを作成してその中に SamplePageViewModel.cs を作成します。ViewModel ではコンストラクタの引数で先ほど作成した Model のインターフェイスを受取り、読み取り専用のプロパティとして View に公開するようにします。

SamplePageViewModel.cs
using EduPrismWpfApp.Modules.SampleModule.Models;

namespace EduPrismWpfApp.Modules.SampleModule.ViewModels
{
    public class SamplePageViewModel
    {
        public ISampleMessageProvider SampleMessageProvider { get; }

        public SamplePageViewModel(ISampleMessageProvider sampleMessageProvider)
        {
            SampleMessageProvider = sampleMessageProvider;
        }
    }
}

View の作成

プロジェクトに Views フォルダを作成してその中に SamplePage.xaml をユーザーコントロールとして作成します。View では ViewModel で公開されているプロパティからモデルに定義されているメッセージ文字列を Label 要素にバインドして表示するようにします。

SamplePage.xaml
<UserControl x:Class="EduPrismWpfApp.Modules.SampleModule.Views.SamplePage"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:prism="http://prismlibrary.com/"             
             prism:ViewModelLocator.AutoWireViewModel="True">
    <Grid>
        <Label Content="{Binding SampleMessageProvider.Message}" HorizontalContentAlignment="Center" VerticalContentAlignment="Center"/>
    </Grid>
</UserControl>

Module の作成

Prism 用と Autofac 用の二つの Module を作成します。まずは Prism 用の Module としてプロジェクトの直下に SampleModule.cs を作成します。このクラスに Prism.Modularity.IModule を継承させて Initialize() で 先ほど作成した View が初期表示されるように処理を追加します。また、画面遷移をおこなうためにコンストラクタの引数で IRegionManager を受取るようにしておきます。

SampleModule.cs
using EduPrismWpfApp.Modules.SampleModule.Views;
using Prism.Modularity;
using Prism.Regions;

namespace EduPrismWpfApp.Modules.SampleModule
{
    /// <summary>
    /// Prism用
    /// </summary>
    public class SampleModule : IModule
    {
        private IRegionManager RegionManager { get; }

        public SampleModule(IRegionManager rm)
        {
            RegionManager = rm;
        }

        public void Initialize()
        {
            // MainRegion に SamplePage を表示
            RegionManager.RegisterViewWithRegion("MainRegion", typeof(SamplePage));
        }
    }
}

Autofac 用の Module としてプロジェクトの直下に SampleModuleRegistry.cs を作成します。このクラスに Autofac.Module を継承させて Load() メソッドを override して Model と View を登録します。

SampleModuleRegistry.cs
using Autofac;
using EduPrismWpfApp.Modules.SampleModule.Models;
using EduPrismWpfApp.Modules.SampleModule.Views;

namespace EduPrismWpfApp.Modules.SampleModule
{
    /// <summary>
    /// Autofac 用
    /// </summary>
    public class SampleModuleRegistry : Module
    {
        protected override void Load(ContainerBuilder builder)
        {
            base.Load(builder);

            // SampleMessageProvider を ISampleMessageProvider として登録
            builder.RegisterType<SampleMessageProvider>().As<ISampleMessageProvider>();
            // SamplePage を登録
            builder.RegisterType<SamplePage>();
        }
    }
}

Shell.xaml とBootstrapper.cs の修正

Shell.xaml に ContentControl 要素を追加して、 Region 名を指定します。リージョン名の指定は prism:RegionManager.RegionName に 文字列を設定することでおこなえます。

Shell.xaml
<Window x:Class="EduPrismWpfApp.Views.Shell"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:prism="http://prismlibrary.com/"             
             prism:ViewModelLocator.AutoWireViewModel="True" 
        Title="EduPrismWpfApp">
    <ContentControl prism:RegionManager.RegionName="MainRegion"/>
</Window>

Bootstrapper クラスに先ほど作成した Module を登録する処理を追加します。追加する内容は以下となります。

  • ConfigureContainerBuilder() に Autofac 用に作成した Module を登録する処理を追加
  • ConfigureModuleCatalog()override して Prism 用に作成した Module を登録する処理を追加
Bootstrapper.cs
using Autofac;
using EduPrismWpfApp.Views;
using Prism.Autofac;
using Prism.Modularity;
using System.Windows;

namespace EduPrismWpfApp
{
    class Bootstrapper : AutofacBootstrapper
    {
        protected override void ConfigureContainerBuilder(ContainerBuilder builder)
        {
            base.ConfigureContainerBuilder(builder);

            // Shell の登録
            builder.RegisterType<Shell>();

            // Autofac Module の登録
            builder.RegisterModule<Modules.SampleModule.SampleModuleRegistry>();
        }

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

            // Prism Module の登録
            var mc = (ModuleCatalog)ModuleCatalog;
            mc.AddModule(typeof(Modules.SampleModule.SampleModule));
        }

        protected override DependencyObject CreateShell()
            => Container.Resolve<Shell>();

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

            //  Shell を MainWindow に設定して表示
            Application.Current.MainWindow = (Shell)Shell;
            Application.Current.MainWindow.Show();
        }
    }
}

この状態で実行すると View が表示されて Model に定義されているメッセージが表示されるのが確認できると思います。

11
14
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
14