最近実験しているのが、GAE/Python + Silverlight という構成のアプリ。GAE/Python で WebAPI を作って、それを Silverlight から呼び出すイメージです。近いうちにこのブログで連載する予定。
この構成で開発していると、GAE/Python のモデルと Silverlight のモデルの整合性を取るのが面倒です。片方にプロパティを追加したけどもう片方には追加し忘れる、というミスがたまに発生します。それに、もしモデルの数が多いと、GAE/Python と Silverlight で同じクラスを作る作業で発狂するかもしれません。
そこで、「GAE/Python のモデルから Silverlight のモデルを生成すればいいじゃん」と考えました。逆はメンドイです。GAE/Python での開発には Kay を使っているので、Kay 用の管理スクリプトとして実装すれば、面倒な GAE のパス設定をしなくて済み、ちょっと楽ができそうです。
作成したスクリプトがこちら。
management.py
# -*- coding: utf-8 -*- from inspect import ( isclass ) from google.appengine.ext import db from kay.db import OwnerProperty import models TYPE_STRINGS = { db.Key: "string", db.StringProperty: "string", db.IntegerProperty: "int", db.DateTimeProperty: "System.DateTime", db.DateProperty: "System.DateTime", db.TimeProperty: "System.DateTime", db.TextProperty: "string", db.ReferenceProperty: "string", db.BooleanProperty: "bool", db.FloatProperty: "float", db.ListProperty: "System.Collections.List<string>", db.StringListProperty: "System.Collections.List<string>", db.UserProperty: "string", OwnerProperty: "string", } def action_generate_models(path="Models.cs"): code = "" for model_name in dir(models): model = models.__dict__[model_name] if not isclass(model): continue if not issubclass(model, db.Model): continue code += generate_code(model) file = open(path, "w") file.write(code) file.close() def generate_code(model): properties = get_properties(model) code = "namespace %s\n" % model.__module__.title() code += "{\n" # データクラスを出力 code += " [System.Runtime.Serialization.DataContract]\n" code += " public partial class %s\n" % model.__name__.title() code += " {\n" for name, type in properties.iteritems(): type_name = TYPE_STRINGS[type] code += ' [System.Runtime.Serialization.DataMember(Name="%s")]\n' % name code += " public %s %s { get;set; }\n" %\ (type_name, name.title()) code += " }\n\n" # メタクラスを出力 code += " public static partial class %sMeta\n" % model.__name__.title() code += " {\n" for name, type in properties.iteritems(): code += ' public static string %s { get { return "%s"; } }\n' %\ (name.title(), name) code += " }\n" code += "}\n\n" return code def get_properties(model): properties = { "key": db.Key, } for prop_name in dir(model): if not prop_name in model.__dict__: continue prop = model.__dict__[prop_name] if not isinstance(prop, db.Property): continue if not prop.__class__ in TYPE_STRINGS: continue properties[prop_name] = prop.__class__ return properties
使い方は Kay の他の管理スクリプトと変わりません。このスクリプトを models.py と同じディレクトリに配置して、manage.py の引数でメソッド名を指定します。
python manage.py generate_models
これで、現在のディレクトリに Models.cs ファイルが出力されます。あとは、Silverlight のプロジェクトから生成したファイルを「リンクとして追加」すればOK。