Nancyメモ

ASP.NETアプリケーションとしてホストした場合の処理フローメモ

Nancy.Hosting.Aspnet.NancyHttpRequestHandler

  • 静的オブジェクト。
  • コンストラクタ内で呼び出すGetBootstrapper()で、
    1. web.configにnancyFxセクションが存在する場合は、そこからオブジェクトを生成する。 ⇒ Nancy-master\src\Nancy.Demo.Hosting.Aspnet\Web.config 参照
    2. NancyBootstrapperLocator経由でBootstrapperオブジェクトを取得する。

Nancy.Bootstrapper.NancyBootstrapperLocator

  • Bootstrapperオブジェクトを生成する。
  • Bootstrapperオブジェクトは静的オブジェクトとして保持している。
  • NancyHttpRequestHandlerの静的コンストラクタで呼び出されている -> 一回だけ呼び出される。
  • DefaultNancyBootstrapper以外でINancyBootstrapperを実装したクラスが存在する場合は、それを使用する。(存在しなければDefaultNancyBootstrapper)

Nancy.DefaultNancyBootstrapper

  • 継承関係: INancyBootstrapper,INancyModuleCatalog -> NancyBootstrapperBase<T> -> NancyBootstrapperWithRequestContainerBase<T> -> DefaultNancyBootstrapper ※<T>にはTinyIoCContainerを指定
  • Initialiseメソッド:
    • NancyHttpRequestHandlerの静的コンストラクタで呼び出されている -> 一回だけ呼び出される。
    • INancyBootstrapperで定義。
    • Bootstrapper生成直後に呼び出しされる。 -> Nancy.Hosting.Aspnet.NancyHttpRequestHandlerのコンストラクタ
    • やってること
      1. アプリケーションコンテナオブジェクトの取得
      2. 対応型情報の取得1? -> DIするときの割り付け情報1?
      3. Conventionsの設定?
      4. 対応型情報の取得2? -> DIするときの割り付け情報2?
      5. 初期化 - GetApplicationRegistrationTasks()使用 -> なにやってるかはよくわからん。
      6. 初期化 - GetApplicationStartupTasks()使用 -> おそらくアプリケーション初期化処理。
      7. 初期化 - ApplicationStartup()呼び出し -> サブクラスでオーバーライドするやつ ※6と7の初期化の違いとして、DIできるかできないかの違いじゃないかなと思う。
      8. FavIconあり時に、アプリケーションパイプライン処理を追加する。
      9. 診断オブジェクトの初期化? -> IDiagnostics実装クラスの初期化処理。なにやってるかはよくわからん。
  • ApplicationStartupメソッド:
    • NancyBootstrapperBaseクラスで定義&ここでは空実装。
    • NancyBootstrapperBase.Initialise()で呼び出ししている。
  • RequestStartupメソッド:
    • NancyBootstrapperBaseクラスで定義
    • 呼び出し階層は GetEngine() -> InitializeRequestPipelines() -> RequestStartup() ※すべてブートストラッパークラス内のメソッド
  • InitializeRequestPipelinesメソッド:
    • パイプラインオブジェクトはは初期化時のものをベースに、リクエスト毎にクローンコピーしたものが使用される。
    • 後述のRequestStartupで設定したパイプラインはそのリクエスト処理時のみ有効となる。
    • また、コンテナもパイプラインと同様。
  • ConfigureRequestContainerメソッド:
    • NancyBootstrapperWithRequestContainerBaseクラスで定義&ここでは空実装。
    • NancyBootstrapperWithRequestContainerBase.GetConfiguredRequestContainer()で呼び出している。-> GetConfiguredRequestContainer()呼び出しは、 GetAllModules(), GetModule(), InitializeRequestPipelines() で行われる。
    • オーバーライドして何を実装することを想定されているのかが、よくわからない。
  • ConfigureApplicationContainerメソッド:
    • NancyBootstrapperBaseクラスで定義&ここでは空実装。
    • NancyBootstrapperBase.Initialise()で呼び出ししている。
    • オーバーライドして、INancyModuleCatalogとIRouteResolverの割り付けを行うことを想定しているようだ。

オーバーライドできるメソッドの呼び出され順は以下の通り

[初回アクセス時のみ呼び出し]

  1. ConfigureApplicationContainer(TContainer existingContainer)
  2. ConfigureConventions(NancyConventions nancyConventions)
  3. ApplicationStartup(TContainer container, IPipelines pipelines)

[リクエスト毎呼び出し]

  1. ConfigureRequestContainer(TContainer container, NancyContext context)
    • RequestStartup()と同様に、InitializeRequestPipelines()内で呼び出されている処理なので、リクエスト毎に呼ばれる。
  2. RequestStartup(TContainer container, IPipelines pipelines, NancyContext context)
    • NancyBootstrapperBase.GetEngine()で行っているRequestPipelinesFactoryの割り付け処理。ここでInitializeRequestPipelines()への参照(という表現で妥当かはわからんけど。)を渡している。RequestPipelinesFactoryはリクエスト毎に呼び出されている -> Nancy.NancyEngineのHandleRequestInternal()での this.RequestPipelinesFactory.Invoke(context);

NancyEngine

  • リクエスト発生時にあらかじめ生成してあるNancyEngineオブジェクトを使ってリクエストをさばく -> NancyHttpRequestHandler.BeginProcessRequest()内
  • NancyEngineはIoCコンテナによってコンストラクタパラメーターが生成されているっぽい。 -> この挙動を設定するには、BootstrapperのConfigureApplicationContainer()をオーバーライドし、コンテナの割り付け情報を変更する。
  • HandleRequestメソッド:
    1. NancyContext生成
    2. プレリクエスト処理 -> 詳細はよくわからん
    3. 静的コンテンツ処理 -> 静的コンテンツへのアクセス時はここで処理して終了
    4. リクエストPipelines生成
    5. リクエストライフサイクル処理*1 -> InvokeRequestLifeCycle()
      1. BeforePipeLineによる処理 -> PipelinesのBeforeを使用
      2. Dispatcherによる処理 -> リクエストのルートに対する処理を行っていると思われる。
      3. AfterPipeLineによる処理 -> PipelinesのAfterを使用
      • 各処理でエラー発生時には、PipelinesのOnErrorを使用したエラー処理が行われる。

ルート解決、ルート処理、レスポンス生成

  • IRequestDispatcherのデフォルト実装であるDefaultRequestDispatcherによって行われる。
  • クラスメンバ構成から想像するに、ルート解決 -> ルート処理 -> レスポンス生成 な流れでリクエスト処理を行っていると想像。




これ以降は次回へつづく?

*1:ここではタスクを組み立てるだけで、実際の処理は行っていない?