C#でのクロスプラットフォームなコマンドラインツール開発に良いかもと考えながら最近のASP.NET 5事情を調べた

2015年10月6日火曜日

ASP.NET 5?

ASP.NET 5はなかなか意欲的なバージョンです。過去のプロジェクト構成を完全に捨て去っていくスタイルです。
私は去年の暮れ*1に割とがっつり調べたのですが、その後に大きく変わった最近の状況にあまりついていけていませんでした。そういうわけで最近の事情について調べた個人的メモです。
[*1] まだASP.NET 5という名前が決まる前で、ASP.NET vNextと呼ばれていました。

軽量でポータブルな実行環境: DNX(旧 K Runtime)

ASP.NET 5では、過去バージョンにあったWindows縛り・.NETランタイムのバージョン縛りや同一サーバ上への複数バージョンインストールに関する厄介事から解放されることになっています。実行環境自体がポータブルになり、サーバ上へのSxSデプロイも超絶簡単(容量面でもコンパクトかつバージョン競合を避けられる方式になる)になるというのが目玉です。
この、実行環境のポータブル性という面で.NET側でおこなわれている取り組み(.NET Coreプロジェクト)はざっくりと2つに分けられます。
  • 軽量かつクロスプラットフォームなサーバ向けランタイム(CoreCLR)の開発
  • クラスライブラリの整備(CoreFX)
CoreFXでは画面描画系をごっそり無視しています。これらのランタイムとクラスライブラリをサーバ上での実行に適した形でパッケージングし、バージョン切り替えや共存をおこないやすく仕立てたものがDNX(.NET Execution Environment)です*2
私がASP.NET 5(当時のvNext)をちまちまと調べていた頃には.NET Coreプロジェクト自体が発表されておらず、非Windowsのクロスプラットフォーム動作においてはMonoを利用するという流れでした。
.NET Frameworkのソースコード公開(https://github.com/Microsoft/referencesource)と、そこから出発してクロスプラットフォーム(LinuxとOS Xを現状で不安定版サポートしている)の64-bitサーバ用環境として育っていくCoreCLRを見ていると不思議な気持ちでもあります。
DNXでは依然.NETアセンブリの実行やアプリケーションコードのビルドにMonoを利用するランタイムオプションを提供していますが、Mono側のバージョン固定が多少面倒な部分は否めません*3。ASP.NET 5の実サーバ運用においてはMonoが絡むシーンは少なくなっていくのでしょう。
[*2] 2015年の1月頃に、K Runtimeと呼ばれていたものが改称されました。
[*3] まあ、Monoに関しては基本的にどんどん最新版を使っていけばいいのですけれど。

.NET CoreはMonoを殺してしまうの?

そもそも極短期では.NET CoreベースのDNXがマトモに動作しないケースも多いため答えを出すまでもないのですが、私はおおむね中期(-3年)まではNo、と考えています。
非Windows環境でのサーバ系需要を.NET Coreが担っていくことは基本的にMonoとXamarinにとっても良いことと見えます。Monoの太古の需要のひとつは非Windows環境でのASP.NETシリーズ実行だったと記憶していますが、この領域は2015年時点でXamarinのビジネス領域から外れています。現時点のXamarinのビジネス領域は確実にモバイル向けのC#開発環境(可能な範囲でのクロスプラットフォームと共に)で、この領域で同社のリソースを振り向けたいことは山ほどあるはずです。そんななかで(外から見ている分には)Xamarinにとってのサーバ向け領域は「できればそろそろやめたい」エリアと見えます。
もちろん、CoreCLRが進化の果てに他領域(たとえばiOSでのfull-AOTサポート)までを広くカバーするようになり、CoreFXについてもGUIツールキットとの連携または取り込みと各OSの膨大なAPIライブラリに対するまともなバインディングが生えてきたとすると、「ん?これXamarin要らんのでは?」となる世界も想定はできます。この筋が通れば見事なdisruptive innovationとなる可能性がありますね。
しかしそれはつまりMicrosoftが本気でXamarinを殺しにかかっているタイミングで、おそらくは相応の資金を投入してXamarinを買収することによって実現すると考えるのが妥当に見えます。そのへんはきっと先の話なのでよくわかりません。

DNXを構成するコマンド群

機能的には以前調べたタイミングからあまり変わっていません。

dnvmコマンド

RubyのrbenvやNode.jsのnodebrewに相当するコマンドです。ホームディレクトリの下に.dnxというディレクトリを作成し、その下へ各バージョンのランタイムを突っ込んでいくスタイルです。.NET Version Managerの略とされています。
前述のポータブルなランタイムをネット上から拾ってきていい感じにシステム上へ配置し、複数のランタイムを共存させたり利用するバージョンを切り替えたりするために使います。ランタイムのアップデートなどがコマンドひとつで完結するので、これまでの.NET系環境と比較するとかなり楽という感じがします。
今のところ非Windows環境でのデフォルトランタイムはMonoです。
CoreCLRを明示してインストールするためには-r(-runtime)オプションでcoreclrを指定する必要があります。
$ dnvm upgrade -r coreclr

...
Determining latest version
Latest version is 1.0.0-beta7
Downloading dnx-coreclr-darwin-x64.1.0.0-beta7 from https://www.nuget.org/api/v2
Download: https://www.nuget.org/api/v2/package/dnx-coreclr-darwin-x64/1.0.0-beta7
######################################################################## 100.0%
Installing to /Users/muo/.dnx/runtimes/dnx-coreclr-darwin-x64.1.0.0-beta7
Adding /Users/muo/.dnx/runtimes/dnx-coreclr-darwin-x64.1.0.0-beta7/bin to process PATH
Updating alias 'default' to 'dnx-coreclr-darwin-x64.1.0.0-beta7'
ランタイムにMonoを利用するとアプリ起動直後にMonoのインストールパスを探して見つかったものを起動しますが、CoreCLRの場合はdnvmでインストールしたランタイムのディレクトリ以下にあるlibcoreclr.dylib(OS Xの場合)を使ってバイナリを実行していく流れです。
以前はkvmというコマンドでした。kvmって他の用語と被りすぎにも程があるという感じのものだったのですが、dnvmとなりました。長いですね。
他のコマンドも芸なく先頭にdn(.NETの意)と付いて4文字になったのか、と思いきやそんなことはないので安心してください。

dnuコマンド

Node.jsのnpmに相当するパッケージ管理系を担うコマンドです。以前はkpmという名前で、そのまんまでした。
DNXのアプリ定義ファイル(JSON形式)に記述されている依存ライブラリをネット上から拾ってきたりできます。
依存ライブラリ管理のみではなく、buildというサブコマンドを使うとアプリのソースをもとにアセンブリを作成できたり、publishを利用するとアプリをデプロイ用に固めたりということができます。
publishかけてrsync一発で動くような楽な感じの構成はとても良いですね。
packサブコマンドを使うとプロジェクトのNuGetパッケージを作成できます*4。MyGetでの自社向けアプリコード配信とか、なかなか手軽な策になりそうで期待が持てます。
ちなみにdnuは.NET Utilityという、色々と諦めた感じの命名です。
[*4] OS X 10.10 + CoreCLR環境では生成に失敗しますが、同Monoではうまく生成できます。

dnxコマンド

dnvmコマンドで拾ってきた.NET実行環境のエントリポイントとなるのがdnxコマンドです。
ちなみに、Mac(OS X)環境で拾ってきたMono版のdnxコマンドの実体は前述のようにシェルスクリプトですがCoreCLR版は普通にMach-Oのバイナリです。
以前はkreというコマンドでした。

CoreCLR+DNXの印象

Linux上はともかく、Mac(OS X)環境でのx64利用について考えるとDNXと組みにするのはMonoよりもCoreCLRのほうが今後楽しそうです。激しく未完成なことを除けば、現時点でもOS X環境で64-bitランタイムを使いたいシーンではMonoよりも扱いやすいです*6。主に、MonoがOS X向けの通常ダウンロードで64-bit版バイナリを提供していない(自前でビルドはできる)ためですが。
CoreCLR+DNXは、実行環境の取得・バージョン固定・アップデートが楽という特性により、クロスプラットフォームなコマンドラインツール*5を作るための優れた基盤となり得るものです。「クロスプラットフォーム動作するユーティリティをサクサク作りたいけどJavaScript書きたくないな〜〜」という人々の大半はPythonが2と3でゴタついている間にgolangへ行った感がありますが、そこC#でもよくね?と考えていくと夢が広がります。
ひとまず、環境をあまり汚さずに導入できるし、Mac用の導入手順が公式サイトにある(http://docs.asp.net/en/latest/getting-started/installing-on-mac.html)のでMacの方も試してみて「なるほどなるほど〜〜」となってみると楽しいかも、という感想でした。
[*5] あ、グラフィックス(GUI)系を扱う必要がある場合にはMonoを使うという具合です。
[*6] というかCoreCLRはまだきちんと32-bit構成持たないんじゃないかな。JIT実行にRyuJITのみを使ってるのなら。

0 件のコメント:

コメントを投稿