47
Silverlight をををを Large-Scale Application ををを - MVVM をを Prism をををを - 鈴鈴 鈴鈴鈴 鈴鈴鈴鈴鈴鈴鈴鈴鈴鈴鈴鈴鈴鈴 鈴鈴鈴鈴鈴鈴鈴鈴鈴鈴鈴 http://blogs.msdn.com/shosuz/ Twitter : @shosuz

Building Silverlight Large Scale Application Using MVVM

Embed Size (px)

DESCRIPTION

MVVM in Silverlight presentation for a SI partner site training in 2010.

Citation preview

Page 1: Building Silverlight Large Scale Application Using MVVM

Silverlight を使ったLarge-Scale Application の構築- MVVM 及び Prism のご紹介 -

鈴木 章太郎アーキテクトエバンジェリストマイクロソフト株式会社http://blogs.msdn.com/shosuz/ Twitter : @shosuz

Page 2: Building Silverlight Large Scale Application Using MVVM

アウトライン

MVVMModel – View – ViewModel何をするものかどこで使えば一番うまく使えるか応用

PrismMVVM を有効に使うためにギャップを埋めるためにオプション

Page 3: Building Silverlight Large Scale Application Using MVVM

ゴール

Silverlight における MVVM の重要性ゴールを達成するためには多くの手段がある

実際に動かしてみよう

MVVM イネーブラについて学ぼうPrism独自のものを作成しよう

Page 4: Building Silverlight Large Scale Application Using MVVM

他にも MV_ とついているものが… ?

MVVMMVCMVPMV????

アプリケーション構築において、メンテナンス性やスケーラビリティ確保のために、一般的に受け入れられているパターン

Page 5: Building Silverlight Large Scale Application Using MVVM

Model-View-ViewModel 全体像MVVM, Prism, MEF - WCF RIA Services 連携

WPF 、 Silverlight の疎結合 ソリューションのパターン下記の実装を行う ( トライアド )

Model Data(Web)Service のエンティティ( をラップする )WCF RIA Services を Model と することも可能

ViewModel Model を UI に合わせて公開する

View ViewModel を XAML 等でバインドする

参照: http://msdn.microsoft.com/ja-jp/magazine/dd458800.aspx

Page 6: Building Silverlight Large Scale Application Using MVVM

MVVMどんなものか?なぜ必要か?

関心の分離View = UI を担当Model = 純粋なデータを含むViewModel = バインディングを通じたView と Model との間のコミュニケーションSilverlight と WPF とで有効活用可能

XAML ベースのデータバインディングテスト可能

Page 7: Building Silverlight Large Scale Application Using MVVM

MVVMどんなものか?なぜ必要か?

Model : INotifyPropertyChanged 、 IDataErrorInfo を実装しているクラス (UI 要素は持たず、 Setter/Getter としてのプロパティを持つのみ )

ViewModel が取り扱うデータを保持するものViewModel : INotifyPropertyChanged を実装しているクラス (UI 要素は持たず、ビジネスロジックやサーバーとの通信を担当する )

多くは ObservableCollection として View にバインドするデータ(Model) を取得し、保持するもの分離コードで Command とイベントハンドラ (Command Receiver) の対応付けを行うExpression Blend のオブジェクトデータソースとしてスタティックリソース宣言が可能(ドラッグ&ドロップで UI 構築)

 View :XAML による UserControl (UI 要素のみ )ViewModel から提供されるデータ (Model) を 2-ways データバインドにより表示・更新するXAML 側で Command の宣言を行うできれば分離コードを一切もたない dumb コントロールとしての実装が望ましい (ViewModel の割り当てを View の分離コードで実行することもできるが、 View – ViewModel の分離が不明確になる可能性がある )

Page 8: Building Silverlight Large Scale Application Using MVVM

The MVVM のトライアドすべてを一緒に

コントロールにデータを表示

UI フレンドリーなエンティティや、 UI 状態、アクション

データを表すエンティティ

ViewModel

View

Model

Page 9: Building Silverlight Large Scale Application Using MVVM

ModelMVVM

データを表すエンティティどこから取得したデータかは知る必要なし

WCF サービス、 WCF RIA Services 等々バリデーションを含む場合あり

Page 10: Building Silverlight Large Scale Application Using MVVM

ViewMVVM

画面 , UI, Silverlight の UserControl UI のルック & フィールを担当情報を表示バインディングを通じて、 ViewModel とコミュニケート

Page 11: Building Silverlight Large Scale Application Using MVVM

ViewModelMVVM

MVVM トライアドのためのロジックのメインソースModel を View と接続するView を抽象化するView にバインドされた Public プロパティINotifyPropertyChanged と、 INotifyCollectionChanged とによる、バインディングを通じた View との会話バインディングを通じた View からの変更の通知 MVVM トライアドの外部とのコミュニケートのためのサービスの呼び出し

Page 12: Building Silverlight Large Scale Application Using MVVM

MVVM はどこから始めるのが良いか ?MVVM バリエーション

View は ViewModel と何らかの関連性を持つ幾つかの実施可能なオプション

View FirstView Model First

MVVM トライアドの個々のパーツのメンテナンス

Page 13: Building Silverlight Large Scale Application Using MVVM

View First MVVM Variations

ViewModel は View の XAML の中のスタティックなリソースとして宣言される

Expression Blend で作れる

もう一つの方法としては、 ViewModel を View の分離コードで作成する

Page 14: Building Silverlight Large Scale Application Using MVVM

DEMO

View First MVVM

demo

Page 15: Building Silverlight Large Scale Application Using MVVM

ViewModel FirstMVVM バリエーション

View は、 ViewModel のコンストラクタにインジェクト ( =注入 ) される

Example:View が Dependency Injection を使って作成されると、 ViewModel が 作成される

Page 16: Building Silverlight Large Scale Application Using MVVM

View と ViewModel との結び付けMVVM バリエーション

View は ViewModel と何らかの形で一対になるViewModel と View は一旦作成され、中間段階を経て、その後一対となる

Page 17: Building Silverlight Large Scale Application Using MVVM

View と ViewModel との結び付け

vm = new MyVM();view = new MyView();view.DataContext = vm;

// With Unityvm = container.Resolve<IMyVM>();view = container.Resolve<MyView>();

view.DataContext = vm;

Page 18: Building Silverlight Large Scale Application Using MVVM

Prism についていつでも選択可能

Prism は、オプションのセット使いたいものだけを選んで使い、残りは無視して良し

例 : モジュールとコマンドは選ぶが、イベントアグリゲーションとリージョンは無視する

Prism: patterns & practices Composite Application Guidance for WPF and Silverlight site

http://www.codeplex.com/CompositeWPF

Page 19: Building Silverlight Large Scale Application Using MVVM

Prism の技術コンセプト

Container

Commands

Bootstrapper

Regions

Modules

Event Aggregation

Unity and DI

Shell

Page 20: Building Silverlight Large Scale Application Using MVVM

Bootstrapperスタートするための機能

アプリケーションを起動メイン UI コンテナをスタート (Shell)(必要に応じて)モジュールの登録とロードグローバルシングルトンの登録 ( オプション )通常 “ Bootstrapper プロジェクト” に含まれる

Page 21: Building Silverlight Large Scale Application Using MVVM

Shellメイン View

メイン UI コンテナロードされ得るすべての View をホストリージョンに分割可能Shell 自身は、その中に何がロードされるかを知らない

Page 22: Building Silverlight Large Scale Application Using MVVM

RegionsContent エリア

View を配置できる Shell の中のエリア名前を付ける必要ありコンテキストを内包可能 ( オプション )RegionManager により Region をメンテナンス可能

Page 23: Building Silverlight Large Scale Application Using MVVM

ModularitySelf Contained Modules

ユーザーにとってはシームレス分割して開発される他のモジュールを参照してはならないSolution は Modules に分割されるExample:

City government applicationModule 1: Managing land parcelsModule 2: Traffic light administrationModule 4: City Parks

Modules は、 infrastructure と Models  をシェアする

Page 24: Building Silverlight Large Scale Application Using MVVM

Dependency InjectionUnity の利用

Unity 又は他の DI ツール群 ( 例 :Ninject)テスト可能でモック作成抽象化コンテナオブジェクトにより、クラスがそのインターフェースに従って登録されるインターフェースをリクエストされたとき、コンテナは、当該インターフェースと一緒に登録されたクラスを、作成するシングルトンのサポート

Page 25: Building Silverlight Large Scale Application Using MVVM

クラスへのインターフェースの登録

container.RegisterType<IMyViewModel,

MyViewModel>();

Page 26: Building Silverlight Large Scale Application Using MVVM

コンクリート Class の作成

container.Resolve<IMyViewModel>();

Page 27: Building Silverlight Large Scale Application Using MVVM

Infrastructure共通の Tools

Silverlight クラスライブラリプロジェクトモジュールのために共有可能なアイテムを含む

ClassesAssetsResources

何の参照も作成しない純粋なライブラリ

Page 28: Building Silverlight Large Scale Application Using MVVM

Commandingアクションとリアクション

データバインディングを通じた View と ViewModel との間のイベントを許可ViewModel が宣言するのは Command receiverCommand は XAML の中で宣言される

Button - ClickListBox (Selector) – Selected

Command は、 ViewModel の Command receiver にデータバインドされるルールベースで disabled/enabled 設定可能

Page 29: Building Silverlight Large Scale Application Using MVVM

Commanding 実装のための5 つのステップ – 前提

Silverlight 4 プロジェクトにおける ICommand 実装は、数ステップで足りる問い合わせの多い個所なので、下記にCommanding 実装のためのシンプルなテクニックを記述する

Page 30: Building Silverlight Large Scale Application Using MVVM

Commanding 実装のための 5つのステップ – ICommand の実装最初のステップは、 ICommand インターフェースクラスの実装

このクラスは Commanding アスペクトを管理する他にも色々オプションがあるところ、ここではシンプルな ICommand の実装方法を紹介

当該 DelegatedCommand クラスで実装するのは、 ICommand の CanExecute メソッド、Execute メソッド、そして、 CaneExecuteChanged イベントこのコードはそのままコピー &ペーストして利用可能

Page 31: Building Silverlight Large Scale Application Using MVVM

Commanding 実装のための 5 つのステップ – ICommand の実装 ① public class DelegateCommand : ICommand { Func<object, bool> canExecute; Action<object> executeAction; bool canExecuteCache; public DelegateCommand(Action<object> executeAction, Func<object, bool>canExecute) {

this.executeAction = executeAction; this.canExecute = canExecute; } …

Page 32: Building Silverlight Large Scale Application Using MVVM

Commanding 実装のための 5 つのステップ – ICommand の実装 ②#region ICommand Members

public bool CanExecute(object parameter) { bool temp = canExecute(parameter); if (canExecuteCache != temp) { canExecuteCache = temp; if (CanExecuteChanged != null) { CanExecuteChanged(this, new

EventArgs()); } } return canExecuteCache; }

Page 33: Building Silverlight Large Scale Application Using MVVM

Commanding 実装のための 5 つのステップ – ICommand の実装 ②

・・・続き・・・public event EventHandler

CanExecuteChanged; public void Execute(object parameter) { executeAction(parameter); }#endregion}

Page 34: Building Silverlight Large Scale Application Using MVVM

Commanding 実装のための 5 つのステップ – Command の定義

//ICommand を表示するための Public プロパティ を ViewModel に追加// このプロパティは 、通常は、ボタン等により、   View にバインドされる

public ICommand LoadProductsCommand { get;

set; }

Page 35: Building Silverlight Large Scale Application Using MVVM

Commanding 実装のための 5 つのステップ – Command の作成

//ViewModel のコンストラクタの中で、  1 で作成したコマンドプロパティを設定する

LoadProductsCommand =   new DelegateCommand

  (LoadProducts, CanLoadProducts);

Page 36: Building Silverlight Large Scale Application Using MVVM

Commanding 実装のための 5 つのステップ – ViewModel の作成// ViewModel が View からアクセス可能なこと を確認する// 様々な方法があるところ、シンプルに View

の XAML 中の Static Resource として作成

<UserControl.Resources> <local:ProductViewModel

x:Key="vm"/></UserControl.Resources>

Page 37: Building Silverlight Large Scale Application Using MVVM

Commanding 実装のための 5 つのステップ – Command のバインド//ボタンコントロールを追加し、当該コマンドプロパティを ViewModel の中で作ったコマンドにバインドする// 当該 Command に parameter を渡したい場合には、 CommandParameter プロパティを、当該 View の中の要素にバインド できる ( 通常は parameter は必要ないが、例として実装 )

<Button Content="Load" Width="120" Command="{Binding

LoadProductsCommand}" CommandParameter= "{Binding ElementName=

FilterTextBox, Path=Text}" />

Page 38: Building Silverlight Large Scale Application Using MVVM

Commanding 実装のための 5 つのステップ – ProductViewModel 完成品 public class ProductViewModel : ViewModelBase

{ public ProductViewModel(){

this.Products = new ObservableCollection<Product>(); this.AllProducts = new ObservableCollection<Product>();this.AllProducts.Add(new Product { ProductId = 1, ProductName = "Apple" });

this.AllProducts.Add(new Product { ProductId = 2, ProductName = "Orange" });this.AllProducts.Add(new Product { ProductId = 3, ProductName = "Banana" }); this.AllProducts.Add(new Product { ProductId = 4, ProductName = "Pear" })this.AllProducts.Add(new Product { ProductId = 5, ProductName = "Grape" }); this.AllProducts.Add(new Product { ProductId = 6, ProductName = "Grapefruit" });this.AllProducts.Add(new Product { ProductId = 7, ProductName = "Strawberry" })this.AllProducts.Add(new Product { ProductId = 8, ProductName = "Melon" });this.AllProducts.Add(new Product { ProductId = 9, ProductName = "Guava" });this.AllProducts.Add(new Product { ProductId = 10, ProductName = "Kiwi" });this.AllProducts.Add(new Product { ProductId = 11, ProductName = "Pineapple" });this.AllProducts.Add(new Product { ProductId = 12, ProductName = "Mango" });

LoadProductsCommand = new DelegateCommand(LoadProducts, CanLoadProducts); } private void LoadProducts(object param) {

string filter = param as string ?? string.Empty; this.Products.Clear();var query = from p in this.AllProductswhere p.ProductName.ToLower().StartsWith(filter.ToLower())select p;foreach (var item in query) {

this.Products.Add(item);}

} private bool CanLoadProducts(object param) { return true   } public ICommand LoadProductsCommand { get; set; } public ObservableCollection<Product> AllProducts { get; set; } private ObservableCollection<Product> products; public ObservableCollection<Product> Products {

get{

return products}set{ products = value;

this.FirePropertyChanged("Product");}

} }

Page 39: Building Silverlight Large Scale Application Using MVVM

Commanding 実装のための 5 つのステップ – ViewModel Basepublic abstract class ViewModelBase : INotifyPropertyChanged{

public ViewModelBase(){}

public event PropertyChangedEventHandler PropertyChanged;

protected void FirePropertyChanged(string propertyname) {

var handler = PropertyChanged; if (handler != null)

handler  (this, new

PropertyChangedEventArgs(propertyname));}

}

Page 40: Building Silverlight Large Scale Application Using MVVM

Event Aggregatorパブリッシャとサブスクライバ

色々な種類のイベントをパブリッシュ及びサブスクライブ可能にするクロスモジュール化可能サブスクライバによるフィルタリング可能例えば :

1. Shell の中の Menu アイテム上をクリック2. イベントはパブリッシャから呼び出される3. イベントはサブスクライバに受信される4. それにより、当該サブスクライバは、

Shell の中の、ある Region の中の、一つの View をロードする

Page 41: Building Silverlight Large Scale Application Using MVVM

Infrastructure共通の Tools

Infrastructure は、 Silverlight class library プロジェクトクラス、アセット、リソースを含み、モジュール間で共有される他のモジュールを参照してはならないWeb サービスをコールしてはならない純粋なライブラリ

Page 42: Building Silverlight Large Scale Application Using MVVM

DEMO

Modular MVVM and Prism

demo

Page 43: Building Silverlight Large Scale Application Using MVVM

Screen Presentation EnablerScreens を生成する

スクリーン間をナビゲート可能にしなければならないView 同志はお互いのことを知らない独自の Screen Conductor を作成可能

Loading / UnloadingDisplaying / Hidingそのまま終了して良いですか ?自分でクリーンアップしましょう !

Page 44: Building Silverlight Large Scale Application Using MVVM

Screen Presentation FrameworkKey Players

ScreenMVVM トライアドを管理

ScreenFactoryScreen class を作成

ScreenFactoryRegistryScreenFactory ディレクトリ

ScreenConductorScreen のアクティベーションイベントをリッスンしたり、その上で動いたりする

ScreenCollectionScreens を収集する

Page 45: Building Silverlight Large Scale Application Using MVVM

DEMO

Screen Conductor

demo

Page 46: Building Silverlight Large Scale Application Using MVVM

参考情報その他Blog 、チュートリアル、サンプル、等々

Introducing the Earthquake Locator – A Bing Maps Silverlight Application, part 1

http://geekswithblogs.net/bdiaz/archive/2010/03/06/introducing-the-earthquake-locator--a-bing-maps-silverlight-application.aspx  

MVVM Light Toolkithttp://www.galasoft.ch/mvvm/getstarted/

Business Apps Example for Silverlight 3 RTM and .NET RIA Services July Update: Part 25: ViewModel

http://blogs.msdn.com/brada/archive/2009/09/07/business-apps-example-for-silverlight-3-rtm-and-net-ria-services-july-update-viewmodel.aspx

ViewModel Pattern in Silverlight using Behaviorshttp://www.nikhilk.net/Silverlight-ViewModel-Pattern.aspx

Simple Step for Commanding in Silverlight http://devlicio.us/blogs/christopher_bennage/archive/2010/03/03/1-simple-step-for-commanding-in-silverlight.aspx

Page 47: Building Silverlight Large Scale Application Using MVVM

© 2010 Microsoft Corporation. All rights reserved. Microsoft, Windows, Windows Vista and other product names are or may be registered trademarks and/or trademarks in the U.S. and/or other countries.The information herein is for informational purposes only and represents the current view of Microsoft Corporation as of the date of this presentation. Because Microsoft must respond to changing market conditions, it should not be interpreted to be a commitment on the part of Microsoft, and Microsoft cannot guarantee the accuracy of any information provided after the date of this presentation. MICROSOFT MAKES NO WARRANTIES, EXPRESS, IMPLIED OR STATUTORY, AS TO THE INFORMATION IN THIS PRESENTATION.