Adapter Pattern

2017/06/20 WPF::Prism
GoF本にも出てくる古典的なパターンのようです。
詳しくはウィキペディアで。
Adapter Pattern

こんなイメージでしょうか。
既存のクラスAをクラスBから使いたい。
クラスA(Adapteeと呼ぶ)を変更しないで、クラスBに合うインターフェイス(Targetと呼ぶ)を持つ(実装する)アダプタクラスを作る。

PrismではWPFのItemsControl、ContentControl、Selector(クラスA群)をRegion(クラスB)上で使えるようにするためにアダプタパターンが使われています(AとBが逆かもしれん…)。
  • Targetはこれ?Targetの中にTarget(regionTarget)がいるので自信梨。

Prismで学ぶデザインパターン

2017/06/18 WPF::Prism

Prismって何?

現在はオープンソースになっていますがその昔、マイクロソフトのサイトにpatterns & practices(p & Pと略されていたり)と言うページがありました。(今でも残ってました)
patternsはデザインパターン、practicesはベストプラクティスの意味だと思います。アプリを設計する際こうしておけば後々苦労しないよ、という匠達のノウハウ集です。Prism5.0までここで公開されていました。
なんとそれ以前はComposite Application Guidance for WPFとして公開されていたようで、当時の日本語ドキュメントが残ってました(2017/10/01)。消えたようです(2018/06/25)。
このあたり見るとShellやRegion、CompositeCommand、EventAggregatorとNameSpace変わった(Microsoft.Practices.Composite→Microsoft.Practices.Prism→Prism)だけ?と言いたくなります。
(私が昔ダウンロードしたPrismのサンプルソースのNameSpaceはMicrosoft.Practices.Compositeのままでした。気づきませんでした…)

PrismはMVVMパターンのライブラリとして有名ですが、それ以外にも色んなパターン(Dependency Injection:依存性の注入とInversion of Control:制御の反転が別物になってる…。同じものだと思ってました)が使われています。
C#でデザインパターンの勉強を始めようという場合、Prismはなかなか良い教材ではないかと思い始めました。
WPFもデザインパターンも詳しくありませんが、勉強を兼ねてまとめていけたらと思います。

Prismが目指すもの

  • 変化(仕様変更、新たな技術の登場等)に強い、拡張可能でメンテナンスが容易なアプリケーションを作る。
  • 一つの大きな塊を作るのではなく、機能単位で独立した部品を組み合わせるようにすることによって、チーム開発を容易にする。テストも容易になる。

Prismに求めてはいけないもの

  • OCC(Occasionally connected computing:モバイル端末等で回線が切れやすい環境でも同期を保つ。2008版ですが、機械翻訳ではない説明
  • サービスとメッセージのインフラストラクチャ…こんなの
  • 認証(本人確認)と承認(アプリ使用の許可)
  • アプリケーションのパフォーマンス(!)
  • アプリケーションの世代管理
  • エラー制御とフォールトトレランス

インストール

  • Nugetで。Formの付いているのはXamarin.Form用。WPFとUWPは付いていない方を選択。ContainerはDIコンテナのこと? どれも使ったことない、どれ選べばいいの?という人はマイクロソフトさんのUnityあたりがサンプル多いのでは(確認してないので嘘かも)

ドキュメントはどこ?

使われているデザインパターン

Hello World(2013版)

2016/11/19 WPF::Prism
ひょんなことからネットサーフィン中に数年ぶりにPrismに遭遇。
前回も今回も、MVCのプロジェクトを細分化(モジュール化)したくてサンプル探していた気がします。
今回は前回に比べて時間的、気分的に余裕もありHello Worldで初めてのWPFに挑戦してみました。
NuGetのパッケージの構成が変わっていたのと、ネームスペースからMicrosoft.Practicesが消えているので(いつの間にかオープンソースになっている)ちょっと戸惑いましたが、思ったより分かりやすい構造でした。

親のXAML(Shell.xaml)にregionを追加してそこに表示するモジュールはIModule型で作成。

利用可能なModuleの一覧(ModuleCatalog)にModuleを追加する方法には、コード、XAML、config、特定のディレクトリに入れる等あり。
権限(人)単位で制御するにはコードで、インストール場所単位で制御するにはディレクトリにポンが楽そう。

モジュールをどの場所(region)に表示するかを制御するのがRegionManager。
モジュールのコンストラクタがRegionManagerのインスタンスを受け取るので、モジュール側から自分の表示場所を指定できる。
親を変更しなくても、モジュールを追加したり、表示場所を変更したりできそう。
なかなかいい感じ。

作成手順

Task 1:Prismライブラリを利用するソリューションを作成

  • 新規プロジェクトの作成(テンプレート:WPF Application、プロジェクト名:HelloWorld.Desktop)
  • NuGetでPrismライブラリ追加(Prism 6 for WPFとUnity for Prism 6。Prism 6 for WPFとなっているのはXamarin用やWindows 10 UWP用ができているためと思われます。ちょっと気になりますが、ここは横道にそれずにまずWPFで)
  • MainWindow.xamlのファイル名をShell.xamlに変更(最近のテンプレートやサンプルではMainWindowのままになっています
  • リファクタリング機能を使ってMainWindowのClass名もShellに変更
  • Shell.xamlのルートタグ(Window)に xmlns:prism="http://www.codeplex.com/prism" を追加、TitleをMainWindowからHello Worldに変更
  • Gridタグを消して<ItemsControl Name="MainRegion" prism:RegionManager.RegionName="MainRegion"/>に置き変える
  • UnityBootstrapperを継承するBootstrapperクラスを追加。using 部分はそのままだとエラーになるので、下記に修正。
    using System.Windows;
    using Prism.Modularity;
    using Prism.Unity;
    using Microsoft.Practices.Unity;
    
  • App.csでOnStartupを上書きし、Bootstrapperを実行するように変更。不要になったApp.xaml ファイルの StartupUri 属性を削除)。実行してShell.xamlが呼ばれることを確認

Task 2:モジュールを追加する

  • モジュール側の新規プロジェクトを追加(テンプレート:Class Library、プロジェクト名:HelloWorldModule)
  • 参照を追加
    • PresentationCore.dll
    • PresentationFramework.dll
    • WindowsBase.dll
    • System.Xaml.dll
  • Prism関連の参照を追加(親プロジェクトのNugetの管理画面から)
  • Class1.cs のファイル名を HelloWorldModule.csに変更(クラス名も連動して変える)。
  • using Prism.Modularity; を追加
  • IModuleを継承
  • 空のInitialize メソッドを追加
  • フォルダを3つ(Services、ViewModels、Views)追加
  • 親プロジェクトからモジュールのプロジェクトを参照し、BootstrapperのConfigureModuleCatalogメソッドでHelloWorldModuleをModuleCatalogに追加
  • ビルドして実行。見た目は変わらないけれど、HelloWorldModuleのInitializeメソッドが呼ばれていることが分かる。

Task 3: Viewを追加

  • ViewsフォルダにHelloWorldView.xamlを追加
  • Gridタグ内にTextBlockを追加し、Textや見た目を変更
  • HelloWorldModule.csにusing Prism.Regions;を追加
  • region managerへの参照を保存するフィールド変数作成
  • コンストラクタで受け取ったregion managerのインスタンスを上で作った変数に保存
  • 上で作った空のInitializeメソッドでregion managerのRegisterViewWithRegionメソッドを使ってShell.xamlのMainRegionとViewsフォルダのHelloWorldView.xamlを紐付ける
  • ビルドして実行すると、HelloWorldView.xamlの内容が表示される
OK キャンセル 確認 その他