AWebProcedureFrameworkというものを作りました。
何をするものかというと、Webアプリケーションで、「XXを処理しています」という表示を見せた後、「完了しました」という表示を見せる手順を自動化するフレームワークです。ASP.NETで使うものです。主にNetstedHtmlWriterを活用することを想定したものです。
どうしてこんな時期に、こんなものを作ったのか? §
なぜこんなものを作ったのかというと、MagSite1でTrackBackをサポートする際に必要となったためです。たとえば、複数のTrackBack URLを含むコンテンツを書き込むとき、TrackBack pingの送信という手順が発生します。コンテンツ本体はローカルファイルに保存するだけなので、時間が掛かる懸念はありません。まあ、画像ファイルが多数ある場合、縮小に時間が掛かって、なかなか反応が戻ってこない可能性はあり得るのですが。それでも、処理時間も処理結果も、おおむね予測可能で致命的ではありません。
それに対して、TrackBack pingは相手のサーバや途中のネットワークの都合もあるので、どの程度の時間が掛かるか予測することは不可能であり、しかも、完了できない可能性もあります。
その点から考えると、今何をしているのかを利用者に明示しながら処理を1手順ずつ進めることが必要とされると考えたわけです。(MovableTypeでも、TrackBack pingを送信中だというメッセージを表示させつつ作業が進行するので、考えることは同じなのでしょう。たぶん)
なぜフレームワーク化したのか §
まず最初に少し調べてから、だいたいのことは分かりました。
「XXしています」というページを表示させてからヘッダーにREFRESHを付けて、処理後に「完了しました」と表示する別のページに飛ばせば良いわけです。
この程度のことの実現は難しく無いと思いました。
しかし、こういうトリッキーなページ間移動のコードと、エラー対策がちょっと複雑になりそうなTrackBack ping送信機能のコードが一箇所に固まってゴチャゴチャするのは避けたいと思ったわけです。
それに、こういうページ間移動は、これが最後ということは考えられず、しばしば必要に迫られることは目に見えていました。
というわけで、これはフレームワークにしてしまえ!と思ったわけです。
ポイントはNestedHtmlWriter §
AWebProcedureFrameworkは、直接的にはNestedHtmlWriterに依存していません。しかし、「XXしています」と表示する通知(notify)ページ、「完了しました」と表示する結果(result)ページの生成は、TextWriterクラス経由で行うアーキテクチャです。つまり、プログラムでページ内容を生成することが前提です。これは、暗にNestedHtmlWriterをバリバリ使うぜ、ということを示しているわけです。
これが気に入らない人は、ソースをバリバリ改変して使ってもOKです。オープンソースやGPLというわけではありませんが、ソース公開で、利用規約はとてもゆるいものになっています。
単体テストもバッチリ §
もちろん、mockオブジェクトを作成できない場合に、delegateを使ってテスト可能なクラスを設計する方法で書いた方法を使って、単体テストもばっちり書けています。
2004年1月5日16時40分頃追記 §
さて、これを使ってプログラムを書こうかと思ったところ。
ページ生成メソッドが、ページの引数その他の肝心な情報にアクセスできないことに気付きました (汗)
なんて間抜けなんでしょう。
基本的には、ページ情報を丸ごと渡すとか、リクエストとレスポンスのオブジェクトを丸ごと渡せば済む話ですが、これまでの経緯から言えば、そんなに単純には済みません。レスポンスのオブジェクトは設定したヘッダーが見えないのでこれを渡さないように変更した経緯があるので、また渡すのはどうも気が乗りません。仮に渡すとすると、レスポンスのオブジェクトが引数でもらえているにも関わらず、ヘッダーの追加はdelegate経由という変な形になってしまいます。
そういうわけで、悩んだ結果、出力メソッドへは、object型のユーザー定義の参照を渡せるという仕様にしました。この中身は、AWebProcedureFrameworkとしては何も関知しません。あくまで、ユーザー側のメインプログラムと、フレームワークから呼び出されるユーザーメソッドの間で取り決めて使うもの、という位置づけです。通常は、ページのオブジェクト(System.Web.UI.Pageクラスを継承したオブジェクト)を使いますが、他のものを渡しても良い、ということです。
というわけで、即日バージョン0.2にバージョンアップしてしまいました。