none
Page_Load以外のイベントのフックを... RRS feed

  • 質問

  • こちらのフォーラムは、いつも大変参考にさせていただいております。

    今回は、いろいろと検索をかけて調べてみたりはしたのですが、自分ではちょっと解決できない状況に直面してしまい、こちらに質問を投稿することで糸口を見つけたいと思いました。

    環境は、VS2005、.NET Framework 2.0、C# です。

    【質問内容】
    Page_Load以外の画面個別イベントの呼び出し元(またはイベントの生成)メソッドをオーバーライドする方法を知りたい。

    【状況】
    Page_Loadだと、基本クラスのOnLoadメソッドをオーバーライドして、”base.OnLoad(e);”を使用することで既定の処理に機能拡張することができますよね。
    それと同じことを画面個別のイベント(例えばボタンクリックイベント)でも行いたいのです。

    なぜかというと、プログラマがDBクラス(iDispose実装)のインスタンス化やトランザクション制御(TransactionScope)、及び例外処理を意識しなくても済むような独自クラスを作成しようとしています。
    そこで、独自クラスで基本クラスのイベント呼び出しメソッド(Page_Loadだと、基本クラスのOnLoadメソッド)を、usingステートメントを使用した上記DBクラスやトランザクションスコープでスコープ定義をし、さらにtry-catch句にて最終的なエラーハンドリング(派生クラスではthrowのみに制限)をしようと考えています。

    フロントコントローラ、パイプライン モデルやHTTPモジュール、及びページのライフサイクル等、参考になりそうなものはたくさんあったのですが、結局答えに辿り着くことはできませんでした・・・
    それとも、このような仕様は実装不可能なのでしょうか?

    usingステートメントを使用しなければ、ページのライフサイクルで”OnPreInit”、”OnUnload”、”OnError”で実現できるのですが、iDisposeインターフェースを活用したいので。。。
    # 無理であるようなら、先の3つのメソッドをオーバーライドして実現させます。

    有識者の方、どうぞご教授のほどよろしくお願いします。

    2006年9月29日 15:16

回答

  • Lady.BUG 様、囚人 様 ご回答ありがとうございます。

    はい、IHttpHandler.ProcessRequest を override すれば良いという方法を知ることができ、実際に全てのイベントをキャッチすることができました。

     Lady.BUG さんからの引用

    しかし、本当にボタンのクリックでプログラマが何もしなくてもトランザクションが開かれるような仕組みが必要なのか、それは許容できるような仕様とコストなのか、もう1度考え直されたほうがいいのではないかと思います。
    # データベースにまったくアクセスしないであろうボタンを押して、他のデータベースの処理とデッドロックしたら、おそらくユーザは怒りますよね



    え~とですね、独自クラスではDBのオープン、クローズ(iDispose)と各SQLの発行を行うDBクラスを using を使用してインスタンス化するのみで、DBオープン処理自体は、プログラマが必要な箇所でのみコーディングにて実装させようと考えています。

    ただし、

     囚人 さんからの引用

    と言えば聞こえは良いですが、「意識しなくて良いことを意識しなければならない」という問題もあります。



    トランザクションに関して言えば、おっしゃられるとおりですね・・・
    # 試しに TransactionScope() を使ってみました。(ちょっと、やってみたくなってしまい。。。)
    # DbProviderFactory クラスにて、コネクションの作成はうまくいったのですが、
    # なぜかOpen() がフレームワークがタイムアウトするまで返ってきませんでした

    トランザクションもDBのオープンと同様、プログラマのコーディングによる実装に任せるようにします。


    このフォーラムでは、いつも勉強させられることばかりで非常に助かります。
    コメントを下さったお二人にも感謝しております。

    以上。
    2006年10月1日 5:30

すべての返信

  •  necobus さんからの引用
    Page_Loadだと、基本クラスのOnLoadメソッドをオーバーライドして、”base.OnLoad(e);”を使用することで既定の処理に機能拡張することができますよね。
    それと同じことを画面個別のイベント(例えばボタンクリックイベント)でも行いたいのです。
    書かれていることそのものは、同様に、Button.Click であれば、Button.OnClick を override して、base.OnClick を呼び出せば実現できると思います。
    ただし、Page の OnLoad を override するのは Page の派生クラスですが、Button の OnClick を override するのは、当然 Button の派生クラスになりますので、期待されている形にはならないのではないかと思います。
    Page クラスの派生クラスから、乗っている Button クラスのイベントハンドラの呼び出しを直接 override することは不可能です。
     
    また、すべてのイベントを対象としてよいならば、IHttpHandler.ProcessRequest を override すれば、ボタンの Click イベントであろうが、TextBox の Changed イベントであろうが、すべての Postback の処理を override できます。

    public override void ProcessRequest(HttpContext context)
    {
      using (...)
      {
        base.ProcessRequest(context);
      }
    }

     
     
    しかし、本当にボタンのクリックでプログラマが何もしなくてもトランザクションが開かれるような仕組みが必要なのか、それは許容できるような仕様とコストなのか、もう1度考え直されたほうがいいのではないかと思います。
    # データベースにまったくアクセスしないであろうボタンを押して、他のデータベースの処理とデッドロックしたら、おそらくユーザは怒りますよね
     
    2006年9月30日 2:17

  • プログラマがDBクラス(iDispose実装)のインスタンス化やトランザクション制御(TransactionScope)、及び例外処理を意識しなくても済むような独自クラス

    と言えば聞こえは良いですが、「意識しなくて良いことを意識しなければならない」という問題もあります。

    仮に全てのイベントがデータベースにアクセスしたとしても、トランザクションの分離レベルを柔軟に変更する事ができない等、扱い辛くなってしまうのではないでしょうか。

    あくまで一例ですが、例外に関しては HttpApplication.EndRequest (ようは Global.asax)で HttpServerUtility.GetLastError を使って、一律に処理する事が可能です。

    2006年9月30日 6:38
  • Lady.BUG 様、囚人 様 ご回答ありがとうございます。

    はい、IHttpHandler.ProcessRequest を override すれば良いという方法を知ることができ、実際に全てのイベントをキャッチすることができました。

     Lady.BUG さんからの引用

    しかし、本当にボタンのクリックでプログラマが何もしなくてもトランザクションが開かれるような仕組みが必要なのか、それは許容できるような仕様とコストなのか、もう1度考え直されたほうがいいのではないかと思います。
    # データベースにまったくアクセスしないであろうボタンを押して、他のデータベースの処理とデッドロックしたら、おそらくユーザは怒りますよね



    え~とですね、独自クラスではDBのオープン、クローズ(iDispose)と各SQLの発行を行うDBクラスを using を使用してインスタンス化するのみで、DBオープン処理自体は、プログラマが必要な箇所でのみコーディングにて実装させようと考えています。

    ただし、

     囚人 さんからの引用

    と言えば聞こえは良いですが、「意識しなくて良いことを意識しなければならない」という問題もあります。



    トランザクションに関して言えば、おっしゃられるとおりですね・・・
    # 試しに TransactionScope() を使ってみました。(ちょっと、やってみたくなってしまい。。。)
    # DbProviderFactory クラスにて、コネクションの作成はうまくいったのですが、
    # なぜかOpen() がフレームワークがタイムアウトするまで返ってきませんでした

    トランザクションもDBのオープンと同様、プログラマのコーディングによる実装に任せるようにします。


    このフォーラムでは、いつも勉強させられることばかりで非常に助かります。
    コメントを下さったお二人にも感謝しております。

    以上。
    2006年10月1日 5:30