The ASP.NET vNext は Rosylyn コンパイラを利用し、実行前にC# ソースコードのコンパイルとロードを行う。David Fowler 氏は独自の言語を対応させることが可能な KRuntime における "DI-by-design" アプローチ の活用法を示した。
KRuntime は ASP.NET vNext アプリケーションの構築・実行に必要な全要素を伴っている。慣習にならい、ランタイムは"design-time"を認めていない。コンパイルとロードは同時に行われる。これに関しては、KRuntime は複数のローダを保持している。project.json ファイルから依存関係一覧を検証し、依存関係のあるライブラリ群を利用してソースファイルのビルドを実施する。
同プロジェクトの参照ローダは興味深い。デフォルトでは、RosylynProjectReferenceProvider を利用しており RosylynProjectReference を戻り値として返す。名前から指し示す通り、同ローダでは C# ソースのコンパイルとアセンブリのロードに Rosylyn C# コンパイラを利用している。
一方で、この動作を上書きできることを David Fowler 氏は示している。
F# の ASP.NET vNext サポート
Refer David 氏の vNextLanguageSupport github project を閲覧しよう。IProjectReferenceProvider の実装として FSharpProjectReferenceProviderを定義している。同クラスではIMetadataProjectReference のカスタム実装である FSharpProjectReference を戻り値として返している。
FSharpProjectReference は多量な役割を果たしている。同 Emit メソッドでは
- プロジェクト参照を取得
- 一時パスにそれらをコピー
- プロジェクト参照とともにソースファイルを fsc compiler を利用してコンパイル
- 一時領域からファイルを削除
これら両クラスは FSharpSupport プロジェクトに格納されており、コンパイルとアセンブリとしての参照が可能である。これらの実装は F# のサポート用のものであるが、C# で記述されている点が注目だ。
サンプルの F# プロジェクトで利用するため、Refer David 氏はプロジェクトの project.json ファイルにて projectReferenceProviderTypeを定義した。
(スニペット)
"language": { "name": "F#", "assembly": "FSharpSupport", "projectReferenceProviderType": "FSharpSupport.FSharpProjectReferenceProvider" },
この操作だけで自身の ASP.NET vNext アプリケーション内で F# が利用可能になる。startup クラスは C# クラスの代わりに F# を利用している。
本サンプルは F# を利用しているが、同様の方法で CLR がサポートしている任意の言語を利用することができる。すべきことは、IMetadataProjectReference と IProjectReferenceProvider の実装を提供することだ。
Aleksander Heintz 氏は、David氏のサンプルを更に詳細に解説した記事を公開している。
- プロジェクトローダーがどの様に動作しているか
- FSharp Reference Provider の更なる詳細
- F#の実装をロードして戻り値に返す FSharpReferenceProvider の C# 実装をどの様に利用するか(また、これで F# ソースをロードできる)
サンプルは単純なものではない。しかし、KRuntime によってもたらされる組み込み DI の効力を示しており、新機能を追加する際に柔軟な対応が可能になる。KRuntime structure による解説では、Native Process, Host, Managed Entry Point, Application Host を含むランタイムの全レイヤーで依存注入ができる(例として、KRuntime はMono を利用した Linux と OSX で動作する)。
ASP.NET vNext では、Microsoft がどの様に Web フレームワークを構築してデプロイするかの変更を示している。