とりあえず現時点でのまとめ

マルチで動いても効率が良くないので、CEのお仕事は一端休止して、8、9月はWeb方面の人になりますが。*1
っで、CEアプリも基礎部分は出来ていて、後は画面とロジックを作っていくだけの状態にはなっているので、参考までに自分がどんな構成でアプリを作っているか書いてみたり。

とりあえず、ソリューション構成は画像のような感じデスが(・∀・)
以下簡単に解説してみたり。

Context

画面遷移についてはSmart.Windows.Mvcを使用します。
っで、機能毎にViewContextを用意します。
ViewContextとは何かと言えば、スコープとライフサイクルを制限したグローバルみたいなもので(・ω・)
本当にグローバルにしてしまうとライフサイクルが気になるけど、ある機能の間くらいであれば共通域の作業データが存在しても混乱は少ないので、機能単位でViewContextを作成というカンジで。

Control

アプリケーション内で共通的に使うUIについてはコントロールとして実装しています。
アプリ固有の描画を行うCustumListView*2や、独自のカレンダー描画を行うScheduleContorolとか。
CustumListViewはアプリ固有の描画の他に、マウス周りの動作を弄って複数選択時の動作をちと変更。
スタイラスによるタップだと、複数選択って面倒ですからね(´д`;)


あと、画面のヘッダ部(タイトル、バッテリ、時計とかの表示)についても今回はコントロール化しています。
全画面共通であれば別にMainFormに直接機能を実装しても良いんですが、今回はダイアログ表示する子画面とかにも、若干異なる設定(バッテリは表示しない等)でヘッダを表示するのでコントロール化しました。

Hal

ハードウエアの抽象化層です。
ハードウエア周りの特殊な制御を行う場合、レジストリを弄ったり、メーカ提供のライブラリを呼び出したりするわけですが。
それを画面とかから直接行ってしまうと保守性/移植性が下がるので(´・ω・`)
そういう部分は抽象化するレイヤを作るようにします。
この構成では、HalSysが本体の抽象化、HalNetworkは通信網(今回はFOMA網)の抽象化、HalPrinterはBluetoothプリンタの抽象化を行うものとして用意しています。

Models

アプリケーションで使うモデルの定義です。
Models直下のものはアプリケーション内のみで使用するもので。


DataとSettingに関しては、今回のアプリ固有の命名であって、要するにリソース系のデータモデルがSetting、イベント系のデータモデルがDataだと思えばよろし(・ω・)
こいつらのパーシステントにはSmart.CE.IO.FixedRecordFileを使用。


Net下は通信プロトコル(ヘッダ、ボディ)の定義です。
データ構造だけ定義すれば、後の通信はSmart.CE.Net.GRRPのクラスを使うだけで、シリアライズ含めて細かい処理の記述は不要なのです(`・ω・´)


Setについては、今回のアプリではいくつかのモデルは対にして使うケースがあるので、そのタプルの定義です。

Services

アプリケーションで使用するサービス層の定義です。
DataServiceとSettingServiceは、それぞれModels.DataクラスとModels.Settingクラスの操作を行う為のもの。
Dataの方については処理が増えそうなので、対象データ毎にpartialで分割しようかと(´д`)


NetServiceは、RAS制御、FTP、独自プロトコル通信のファサードで。
通信系の処理の実装自体は、Smart.CE.Netのクラス達にお任せです(`・ω・´)


後の、LinkServiceはPCとのデータ同期、PrinterServiceはBluetoothプリンタを使った印刷処理の機能を提供するものです。

Operations

良い名前が思いつかなかったので、とりあえずOperationsと名付けてみましたが(´д`;)
Servicesがアトミックな個々の処理を提供するモノなのに対して、それらをまとめて順次呼び出すようなものがOperationsという位置づけです。
確認メッセージの表示、ダイアルアップ、ダウンロード、切断、ファイル更新、通信間のHW制御といった一連の処理だとか。
これらの処理をViewに書くのも違うし、複数の機能で共通で使用するものもあるので、ViewとServiceの中間層(Service群のファサード(・ω・)?)というカンジで用意しています。

Utils

暗号化と圧縮については、後述のNativeHelperを参照。
UnitOfWorkは、データ編集の都合上あると便利なので用意してみました(・ω・)

Views

各画面のView(Smart.Windows.Mvcを使って遷移するもの)と、モーダル表示するダイアログについては、そのベースとしてAppViewBase、AppDialogBaseを用意して、UI周りの共通設定なんかはここで実装しています。
ViewIdは画面IDの定義で、ViewUtilはビューヘルパというか、UI系の拡張メソッドとかはViewUtilで定義です。


Views下のInfoとInputは共通ダイアログ系の画面です。
独自メッセージボックスやBackgroundWorkerを使うプログレス画面なんかの表示系と、Smart.CE.Windows.Forms.SipControlを使った電卓入力なんかの入力系になります。


あとは、機能毎にサブフォルダを作ってその下に各機能のViewを配置しています。
管理機能については、Admin下に更にサブフォルダを作って配置しています。
管理機能といいつつ、アプリの管理機能というよりはシステム全体への指示端末機能も入っていたりして、なんかそれだけで一つの別アプリケーションになっていたりしますが(´д`;)

その他

プロジェクト直下のクラスについてです。


Componentsは、サービスロケータとかそんなんです(・∀・)
ちゃんとDIするまでもない小規模なアプリとかで、コンポーネントの構築を行う場所として、こういうものを用意しています。*3


IApplicationControlは、アプリケーションの全体制御を行う為のインタフェースです。
例えば、ロックしてログイン画面の表示だとか。
なお、インタフェースの実装自体はMainFormで行っています。


Loggingはアプリケーション固有のフォーマットを行うログ出力機能です。
内部でのログのプリミティブな処理は、Smart.CE.Logのクラスを使っています。


Sessionはまあ、要するにグローバルデータです(´д`)
アプリ全体で使用するものについては、Contextではなく別途こいつを用意してComponentsで構築するようにしていたり。
まあ、なんでもここに突っ込むと堕落してしまうので、Sessionクラスで管理するのはログイン中のユーザ情報のみだったりしますけど。


っで、MainFormはSmartWindows.Mvc.Controllerのホストと、IApplicationControlの実装が主要機能です(・ω・)



っと、ここまでがアプリケーション本体のプロジェクトの構成になります。
後は、アプリケーションで使用しているライブラリ(他のプロジェクト)について少し補足を。


NativeHelper

libで提供されている機能を、DllImportして使うためだけに用意しています。
提供する機能は暗号化と圧縮。
圧縮処理の方はPure .NETでも書けなくは無いんですが、現行仕様からわざわざ変えることもないのでNativeなDLLでの提供にしました(・ω・)

Smart.CE

Windows CEアプリケーションを作成するためのライブラリ群です。
ライブラリについては、大体以下の3パターンに分けられます。

  • その1 Compact Frameworkでサポートされない機能の代替

例えば、上の方でBackgroundWorkerとか言っていますが、標準のCompact Frameworkではサポートされていなくて(´・ω・`)
そういうものについては、同等の処理を自前で用意しています。
まあ、本家でサポートされるようになれば不要になるものですが(´д`;)


例えば、OpenNetCFのSmart Device Frameworkとかにもそういうクラスがあったりしますが。
普段使うものについては自前実装を持っているので、自分はSmart Device Frameworkを必要としていなかったりして(・ω・)

この辺はまあ、Compact Framework以外でもよくあるものですが(・ω・)
ある程度の実装は自前で持っているので、コンポーネントとか買ってこなくてもいいや、みたいな(・∀・)
テキストやボタンとかのUI拡張にしろ、FTPとかの通信系にしろ、一からちゃんと実装するのは面倒な部分もありますが、一端作ってしまえば資産として流用しやすいところであって。


ちなみに、まだ納得していない所はSmart.CE本体には未マージだったりね(´д`;)
どの辺りかと言うと、Data.Mapper(再設計したい)、Net.Mail(MIME系をちと再考したい)、Net.NetworkInformation(WLAN周りのDeviceIoControlとiphelperだけど、Full Frameworkに似せたインタフェースにしたい)とかの機能。
これらの処理については、とりあえず現行レベルでも使える実装はあるんだけど、インタフェースをもう少し格好良くしたいな〜とか考えているモノです(´д`;)
まあ、おいおい本体にマージしていく方向で。

  • その3 業務アプリケーション向け機能

ハンディターミナルを使った、業務アプリケーションを作成するのによくある処理をライブラリ化したものです
想定しているドメインは、リテール、ロジスティクス、調査業務とかですが(・ω・)
画面ヘッダ部に表示するバッテリ、通信状態、時計なんかの状態一元管理機能も共通のニーズから生まれてきたものですし。
Smart.Windows.Mvcなんかも、業務アプリケーションでの頻出パターンを考えて生まれてきたものですが。



…っと、自分がCEアプリを作る場合はこんな構成にしているよ、っという例でした。
サンプルレベルならともかく、人様が作ったフル実装のアプリケーションの構成ってあまり見ることも無いと思うので、例を一つ書いてみたわけですが、どうでしょう(・∀・)?


ところで、ロジックの記述に拡張メソッドLINQ(to Object)、yeildを多用しだすと、なんかLLっぽいな〜と改めて思ったりしてね(´Д`)

*1:片方の仕事に飽きてきたら、息抜きにもう片方の仕事をやりだすかもしれないけど(´д`;)

*2:オーナードローの基本機能自体はSmart.CE.Windows.ListViewExで定義。

*3:手抜きの時にはよくこういうものを作ったりして(´д`;)