はじめに
今から12、3年前……すごい昔です(笑)
業務でエンティティクラスをせっせと手書きしていた頃の話です。「面倒だな」と思い、データディクショナリからカラム名を引っ張ってきて、SQLで「public string カラム名 { get; set; }」をそのままクエリの実行結果として吐き出す、という小技をやり出したのが最初です。
幸いその現場はカラム名がパスカルケースだったので、これだけで十分満足していました。
後に型もstring固定からCASE文でDB型→C#型に変換し、しばらくはこのSQLスクリプトで満足していましたが、現場が変わってカラム名がスネークケースになった...というか戻ったので、ちょっと困ったんです。
「先頭以外を小文字にしてアンダースコアを消す…」を繰り返す、だってこれやるの無理でしょ。
なのでSQLをやめ、直接貼り付けたカラム名をスネークからパスカルに変換するC#を書きました。
その後、業務でExcel出力を実装した際に、Officeを使わなくても取り込めるんだと知り、最終的にExcelからも取り込む機能を追加し、ついでに論理名のセルからsummaryも生成できるようにしています。
自分で作っておいて何なんですが、項目数不足やスペルミスがなくなり、そもそも実装速度が飛躍的に上がり、かなり重宝しました。
ただこのツールは完全に自分用で、見た目もお世辞にも良くなく、ViewModelを作る機能も当時の現場専用だったりしたので、ラジオボタン選択時の項目制御やレイアウトを整え、人に見せても恥ずかしくない形にしたのが、今回紹介する EntityGenerator です。
EntityGeneratorでできること
- 入力元はExcel(テーブル定義書)または直接入力(1行1項目のカラム名)
- 生成対象はプロパティ / ViewModel(CommunityToolkit.Mvvmの[ObservableProperty]形式)/ 命名規則変換のみ、から選択
- 命名規則はパスカルケース / キャメルケース / 大文字 / 小文字 / 物理名のまま、から選択
- 出力は画面表示 / .csファイル出力
- 定義書上のデータ型とC#のデータ型のマッピングはJSONファイルで自由にカスタマイズ可能
プログラムによる機械的な変換で名称を生成するため、定義書の記述さえ正しければ、手作業特有の命名揺らぎやスペルミスが混入する余地がありません。速度だけでなく、この正確性も狙いの一つです。
設計判断:あえてログもリッチなエラーハンドリングも入れていない
このツールは製品として配布することを想定しておらず、社内での業務改善用に「困ったらソースを直接書き換えて使う」ことを前提にしています。そのため、ログ出力の仕組みは設けず、エラーハンドリングも最小限にとどめています。
これは手を抜いたわけではなく、意図的な判断です。使う人(=作った本人や身近な同僚)がソースにすぐアクセスできて、動作に違和感があればデバッグ実行して直接確認・修正できるなら、ログ基盤やユーザー向けの丁寧なエラーメッセージにコストをかける優先度は低くなります。エラーを握りつぶしているところも、設定ファイルの読み込み失敗時など「代替手段がなく握りつぶす以外に取りようがない」箇所に限定しています。
同時期に作っていたGnssSimulator(GPS/GNSS位置情報の検証ツール)の方は、他人の環境にインストールして使ってもらうことを想定しているため、逆にログ出力の仕組みをきちんと作り込んでいます。
データ型マッピングをJSONで外出しにした理由
定義書上のデータ型表記(「文字列」「整数」「日付時刻」など)とC#の型(string、int、DateTimeなど)の対応表は、チームや現場によって表記ゆれがあります。ここをコードにハードコーディングしてしまうと、表記が変わるたびに再ビルドが必要になってしまいます。
[
{ "DefDataType": "文字列", "CsDataType": "string" },
{ "DefDataType": "整数", "CsDataType": "int" },
{ "DefDataType": "日付時刻", "CsDataType": "DateTime" }
]
初回起動時に%APPDATA%配下へこのJSONを生成し、以降は編集して「データ型定義再読込」ボタンを押すだけで反映される形にしています。ビルドし直さずに現場ごとの表記ゆれに対応できるので、細かい機能ですが実用面では効いてきます。
技術構成
-
CommunityToolkit.Mvvm:
[ObservableProperty]/[RelayCommand]でMVVMを実装 - ClosedXML:Excelのテーブル定義書の読み込みに使用
コード生成部分(プロパティ/ViewModelの出力ロジック)は独立した処理として実装しているため、差し替えればJavaのBeanクラスなど他言語の同種のボイラープレートコード生成にも応用できる構造にしています。
おわりに
そもそも「困ったら中身を書き換えて使えばいい」というスタンスで作っているツールです。MITライセンスで公開しているので、興味があれば覗いてみてください。自分の現場の命名規則やデータ型に合わせて、cloneして自由に改造してもらって構いません。