いま.NETで業務アプリを作成するんだったらRIA Serviceフレームワークを利用する
今.NETで業務アプリを作成するのであればRIAService+Silverlightを使うことを勧めするだろうな。理由は高い生産性。
サーバー側の仕組みはEntity FrameworkとRIA Serviceで本当に簡単に作成できるし、クライアント側についてもRIA Serviceの呼び出しやエンティティを生成してくれる。しかも、アグリゲータやプレゼンテーションモデルの概念が組み込まれているので単なるテーブルのCRUDレベルではない機能についても十分実用的に利用できる点が素晴らしい。
RIAアプリが簡単に作れる
どの程度の手間でアプリが作成できるか、AdventureWorksLTデータベースを使って以下のようなTreeViewをカテゴリを選択して製品一覧を表示し編集できる画面を作成したみた。
RIAServiceのプロジェクトを作成
まず最初にRIAServiceのプロジェクトを作成する。Silverlightビジネスアプリケーションを利用するとページ遷移方式のSilverlightアプリでひな形を作成してくれる。
Entity Frameworkのモデルを作成
データベース処理はEntity Frameworkを利用する。RIA Serviceとの連携機能が充実しているためである。ウイザードで利用するテーブルを選択すると自動的にモデルを作成してくれる。リレーション関係があればナビゲーション用のプロパティも作成してくれる。
ドメインサービスの作成
Entity Frameworkで作成したモデルに対するCRUD操作用のサービスについても自動生成で作成できる。
ここで初めてコードを記述するが、検索対象の関連データを自動的に取得するための指示をするために、検索処理時とモデルのメタ情報に対して数行記述する。この部分のカスタマイズでさまざまな機能追加が行うことができる。
public class ProductDomainService : LinqToEntitiesDomainService<AdventureWorksLTEntities> { public IQueryable<Product> GetProduct() { return this.ObjectContext.Product .Include("ProductModel") .Include("ProductCategory"); ; }
internal sealed class ProductMetadata { [Include] public ProductCategory ProductCategory { get; set; } [Include] public ProductModel ProductModel { get; set; }
サーバー側で記述するコードは今回これだけ。非常に少ないコーディング量で済んでいる。今回更新系の処理の追記は行っていないが、自動生成コードがひな形にもなっており、わかりやすい形でコード追加できるようになっている。
クライアント側の作成
今度はクライアントであるが、先ほど作成したサービスの呼び出しの仕組みは自動生成されるので、実画面を作成することに集中できる。Silverlightを使うとサーバーと同じプログラム言語であるC#で画面側も作成することができる。JQueryなどのライブラリの普及でHTML+JavaScriptでかなりのことができるようになったが、現時点ではSilverlightのほうがまだまだ生産性が高いと思っている。さらに、SliverlightがMVVMパターンの実装をサポートしている点もメリットに感じる。ドメインモデルがビジネスロジックの抽象化を助けドメイン層の複雑さとの戦いの武器になるように、MVVMのViewModelは画面層の複雑な制御の戦いの武器になるからである。今回もMVVMパターンで実装するが、フレームワークがあると便利なのでViewMakerを利用している。
作成したViewModelは、画面の主要構造であるTreeView、一覧表示(DataGrid)、詳細(Grid)をViewModelのプロパティで表現したクラスで、あと検索、更新処理用のメソッドを持っている。今回ViewMakerの機能を利用してViewModelから画面(View)を生成しレイアウトを調整して最終画面を作成したが、もちろんViewMakerを使わずにView(XAML)を直接作成しても大きな違いはない。
public class ProductListViewModel : ViewModelBase { public ProductListViewModel() { context.Load(context.GetProductCategoryQuery(), (x) => OnPropertyChanged("ProductCategoryTree"), null); context.Load(context.GetProductModelQuery()); } private ProductDomainContext context = new ProductDomainContext(); [View(ViewControlType.TreeView)] [ViewProperty(TreeViewControl.Properties.ItemsSource, "Children")] [ViewProperty(TreeViewControl.Properties.DisplayMember, "Name")] [ViewProperty(TreeViewControl.Properties.SelectedObject, "SelectedCategory")] public IEnumerable<ProductCategoryTreeViewModel> ProductCategoryTree { get { return context.ProductCategories.Where(x => x.ParentProductCategoryID == null) .Select(x => new ProductCategoryTreeViewModel(context.ProductCategories, x)); } } [View(ViewControlType.DataGrid)] public EntitySet<Product> Products { get { return context.Products; } } ... public ICommand QueryCommand { get { return this.CreateCommand(QueryAction); } } private void QueryAction() { if (!Validate()) return; var query = context.GetProductQuery(); if (SelectedCategory != null) query = query.Where(x => x.ProductCategoryID == SelectedCategory.ProductCategoryID); context.Products.Clear(); context.Load(query.Take(20)); } public ICommand UpdateCommand { get { return this.CreateCommand(UpdateAction, (x)=>this.Products.HasChanges); } } private void UpdateAction() { if (!Validate()) return; context.SubmitChanges(); } }
ちなみに、ViewModelの実装量はVisual Studioのコードメトリックスで計測すると合計で53行程度であった。ViewModelより自動生成させた画面をViewMakerの実行時編集機能を使って最終化すれば完成になる。
上記をViewMakerを利用して下記のように編集する。
まとめ
RIA Serveice+Silverlightの実装はVisual Studioの充実したサポートがあり高い生産性が期待できるため、業務アプリを作成する場合に検討することをお勧めする。なお、より複雑ドメインモデルやViewModelの実装についてはBurgerShop Sampleを参考にしていただきたい。