Boost」など、さまざまなカンファレンスを企画・運営しています。BOOKS(コードジン・ブックス)は、CodeZineの連載からカットアップした、開発現場の課題解決に役立つ書籍シリーズです。4その他のサービスメソッドの呼び出し更新時のエラー処理TimeStamp列を利用した同時実効性制御まとめ参考資料メタデータクラスによる表示データの制御と値の検証メタデータクラスはエンティティクラスの対となるクラスで、エンティティデータの属性情報を定義するクラスです。対になって1つのクラスを表すため、「バディクラス」と呼ばれることもあります。Studioのウィザードからドメインサービスを作成すると、エンティティクラスのインナークラスとして、メタデータクラスが作成されます。Servicesでは、データの検証情報やUIに表示させるための表示名、表示順序などのメタ情報をメタデータクラス側に定義することで、エンティティクラス側がウィザードなどで再生成されても、ユーザが定義したメタ情報が失われないようになっています。リスト1は、お小遣い明細クラスに対し、メタデータクラスを通じてデータの表示方法や検証情報を追加した例です。3で強化されたスタイルと値の検証』(CodeZine)を参照してください。ErrorMessage="{0}は{1}から{2}の間で入力してください。ここで注目するのは、お小遣い明細クラスに指定された属性情報です。MetadataTypeAttribute属性は、指定されたクラスに対するメタデータクラスを指定するための属性です。お小遣い明細クラスの本体は「お小遣いEntites.Designer.cs」にパーシャルクラスとして定義されているので、ここではメタデータクラスの指定のみを行っています。前編でデータグリッドに表示するサンプルを作成した後なので、Silverlight側のUIには特に変化はありません。Studioのデザイナーに伝えることができます。最終更新日プロパティはサーバ側で自動的に割り振るデータであるため、クライアント側には追加されないように、Exclude属性を追加しています。逆に、クライアント側に追加する場合に指定する属性は、Include属性です。Include属性はデフォルトで有効になるため、明示的に定義する必要はありません。この状態で前編のサンプルを起動し、連番に「21」といった範囲外の数字を入力すると、図4のように値の検証が行われ、正しい値を入力するか、入力をキャンセルするまでデータを確定できません。メタデータによる値の検証では、自動生成されたコード側を確認してみましょう。Silverlightプロジェクトの「Generated_Code」フォルダの「RIAServicesSample.Web.g.cs」から、お小遣い明細クラスを探してください。リスト1で定義した通り、自動生成されたコードでは、お小遣い明細Metadataクラスの情報が、お小遣い明細クラスのプロパティに定義されていることを確認できます(リスト2)。ErrorMessage="{0}は{1}から{2}の間で入力してください。このようにメタデータクラスを利用することで、データの検証情報とデザイン時の表示内容を、サーバ側で定義できます。共有コードここまでで、エンティティクラスにはデータモデルの定義を、メタデータクラスにはデータの属性情報を定義してきました。データの振る舞いを追加するには、どんな方法があるでしょうか。1つは後述するドメインサービスに定義する方法で、もう1つは共有コードに記述する方法です。共有コードは、サーバとクライアントでコードを共有するしくみです。新しくお小遣い帳のレコードを作成して初期化するコードは、サーバ側とクライアント側で同じコードを利用するはずです。このようなコードを記述したい場合、「*.share.cs」といった命名規則のクラスをソリューションに追加します。ここでは、お小遣い帳クラスのパーシャルクラスとして「お小遣い明細.share.cs」という名前の共有コードを作成しました。Serviceリンクが設定されたプロジェクトであれば、どこであっても問題ありません。重要なのは、拡張子が「*.share.cs」であることです。ドメインサービスに定義されたメソッドの違いは、ドメインサービスのメソッドはあくまでサーバにあり、WCFを通じて呼び出すのに対し、共有コードのメソッドはクライアントにコピーされ、クライアントで動作します。今回追加した共有コードをリスト3に示します。この例では、単純にお小遣い明細の日付プロパティに当日の日付を設定しているだけです。このコードをコンパイルすると、Silverlightプロジェクトの「Generate_Code」フォルダに、サーバ側のプロジェクトで定義した「お小遣い明細.shared.cs」と同じファイルが生成されるのを確認できます。このように共有コードを利用することで、エンティティのパーシャルクラスのコードやユーティリティクラスのコードを、サーバとクライアントで共有できます(図5)。Servicesを利用していると、サーバ側に登録されたサービスであっても、まるでローカルにあるクラスのメソッドのように利用できます。当たり前のことですが、サーバ側に登録されたサービスを利用するには、データセンターなどの遠隔地にあるサービスを呼び出すことになり、パフォーマンス面では大きなデメリットになります。この手の問題は、開発時には、サービスを提供するサーバと、Silverlightが動作するサーバが同じであるため問題になりませんが、サービス提供時やパフォーマンステスト時など、プロジェクト後半になって問題が表面化することが多いです。一概にこうすれば良いという解決策はありませんが、特にサーバリソースを必要としないユーティリティ的なロジックは、共有コードにしてクライアント側にコードを同期させるというのも、1つの方法だと筆者は考えます。NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Technologies。執筆コミュニティ「WINGSプロジェクト」代表。