April 2016

Volume 31 Number 4

.NET Core - .NET Core による .NET のクロスプラットフォームへの移行

Phillip Carter | April 2016

マイクロソフトは、.NET の新たな実装として .NET Core をビルドしています。この .NET Core により、開発者はクラウドに最適化されたワークロード向けにクロスプラットフォーム コードを作成できるようになります。このオープン ソース開発には多くの開発者から歓迎の声があがっていますが、.NET Core の登場には具体的にどのような意味があるのでしょう。そこで今回は、.NET Core の現状とその目標、.NET Core と Microsoft .NET Framework の関係、.NET Core に着手する際に使用できるコマンドライン ツールについての基礎知識を取り上げます。

.NET Core とは

.NET Core を理解するには、.NET 自体を理解することが重要です。多くの開発者は「.NET」と言うと「.NET Framework」を想像しますが、それだけではありません。.NET とは、さまざまな実装を含む ECMA 標準です。こうした実装には .NET Framework、Mono、Unity などがあり、今回これに .NET Core が加わります。つまり、.NET Framework と .NET Core は多くのエクスペリエンスを共有します。ただし、.NET Core はいくつか異なる原理を念頭に新たに生み出された実装です。

まず、.NET Core はクロスプラットフォーム対応です。Windows、OS X、Linux の複数のディストリビューションで動作します。さまざまな CPU アーキテクチャもサポートします。マイクロソフトは、.NET Core を可能な限り多くの場所で実行するという最終目標を掲げて、サポート対象の Linux ディストリビューションと CPU アーキテクチャを増やしています。

同時に、.NET Core はデザインとアーキテクチャの点で根本的にモジュール構造です。ランタイム、ライブラリ、コンパイラなどのコンポーネントはすべて、適切に設計されたインターフェイスを介してやり取りする個別のエンティティです。そのため、特定のニーズに応じてコンポーネントの「交換」が可能です。ライブラリ自体もモジュール構造になっていて、NuGet を通じて配布されます。そのため、使用するライブラリを必要なものだけに限定し、システムに合わせて .NET Core のフットプリントを微調整することができます。

また、.NET Core に対して記述されたコードは移植可能で、サポート対象のさまざまなプラットフォームで実行するように調整できます。プロジェクトのターゲットに応じて、.NET Core コードを .NET Framework、Mono、Xamarin の各プラットフォーム、および Windows 8、Windows Phone、ユニバーサル Windows プラットフォーム (UWP) で実行できます。詳細については、.NET Platform Standard (bit.ly/1Of6W1r、英語) を参照してください。

最後に、.NET Core は利用する分しかコストがかからないので、コスト効率は高くなります。.NET Core の取り組みが目指す 1 つの目標は、抽象化にかかるコストを開発者が明確に把握できるようにすることです。そのため、利用する分だけにコストがかかるモデルを実装し、問題解決のために高いレベルの抽象化を利用することで必要なコストが明確になるようにしています。抽象化は無償で実現することはできません。そして、コストを開発者に隠すようではいけません。さらに、.NET Core は標準ライブラリによるパフォーマンスを優先し、メモリの割り当てやシステムにおけるメモリのフットプリント全体を最小限に抑えています。

.NET Core 向けのシナリオ

現在、.NET Core 向けにコードを作成できるシナリオは 4 つあります。クロスプラットフォーム ASP.NET Web アプリ、クロスプラットフォーム コンソール アプリ、クロスプラットフォーム ライブラリとフレームワーク、UWP の 4 つです。

速度を重視してビルドされた ASP.NET Core 1.0 は、.NET Core 向けのクロスプラットフォーム Web スタックです。Linux 上 のコンテナーへの ASP.NET Web アプリの配置のように、これまで実行できなかった操作も実現できるようになりました。ASP.NET Core が提供する機能の範囲については、bit.ly/1TqPcIo (英語) を参照してください。

クロスプラットフォーム コンソール アプリには、多くの開発者が考えるよりもかなり大きなスコープがあります。たとえば ASP.NET Core Web アプリは、極端に言えば、情報を読み取ってポートに書き込むコンソール アプリです。システム全体のバックエンドを形成する一連のマイクロサービスは、それぞれコンソール アプリとして記述することも可能です。

クロスプラットフォームのライブラリとフレームワークの区別は 1 つの基準にすぎません。ライブラリは、.NET Core を基盤にビルドする場合に最も自然な候補の 1 つです。しかし、もっと基準を広げると、分散コンピューティング向けのフレームワークなども優れた候補になります。

最後に、Windows 10 デバイス ファミリをターゲットにする UWP アプリは .NET Core 上で実行されます。リッチな Windows 10 アプリをビルドするために .NET Core のライブラリを組み込んで、フル機能を装備する UWP アプリをビルドできます。

つまり、現状、.NET Core 向けに作成できるものは数多く存在します。ツールが成熟し、拡張されるにつれて、ビルドできるものは今後さらに増えていくでしょう。

この 4 つのうちいずれかのシナリオに当てはまる.NET Framework の資産が手元にある場合、または新しいテクノロジを経験してみたい場合は、bit.ly/1Q1Q18q (英語) を参照して .NET Core コードの作成に着手することができます。

.NET Core と .NET Framework の比較

ほとんどの開発者が認識し、使い慣れている .NET は、.NET Framework です。それでは、.NET Core と .NET Framework にはどのような違いがあるのでしょう。最初に留意することは、どちらもすべてのコードの作成に同じ言語 (C#、F#、Visual Basic) を使用します。コードを作成するエクスペリエンスは、いつも使い慣れたルック アンド フィールになります。ただし、.NET Core は新しいスタックで、.NET Framework のサブセットではありません。.NET Core と .NET Framework は共に進化する同一の 2 つのスタックとして考えるのが適切です。

.NET Framework は、Windows 7 から Windows 10 向けのデスクトップ アプリケーションを作成する際に使用するスタックで、今後もそれは変わりません。事実、.NET Framework と .NET Core のコードは、同じソリューションで互いの機能を損なうことなく共存できます。たとえば、.NET Framework GUI (Windows フォーム) で .NET Core で作成されたサービスを利用するシナリオを考えます。

.NET Core と .NET Framework の共通点と相違点を考える場合、API サーフェス領域とランタイム機能の 2 つの視点から考えるとわかりやすくなります。図 1 は、2 つのプラットフォームで重複する API を示しています。

.NET Framework と .NET Core で共通する API のサブセット
図 1 .NET Framework と .NET Core で共通する API のサブセット

.NET Core と .NET Framework には、どちらにも実装される .NET API があります (ただし、基盤となる実装は異なることがあります)。同時に、.NET Core と .NET Framework のどちらにも、他方にはない独自の API と機能があります。たとえば、.NET Framework には、.NET Core には存在しない GUI フレームワークと Windows 固有の API が複数存在します。同じく、.NET Core にも .NET Framework にはないクロスプラットフォームの機能と API があります。

また、.NET Framework は、Windows 更新プログラムの対象となる Windows コンポーネントです。しかし .NET Core は、稼働する場所やサービスを提供する方法にまったく異なるモデルを使用します。.NET Core は、NuGet のパッケージから構成され、アプリのローカルにインストールされるランタイムを備えています。つまり、アプリは .NET Core を「組み込む」かたちで配布されるため、コンピューターやデバイス上の他の .NET Core インスタンスとサイドバイサイドで実行することができます。そのため、.Net Core の更新サービスの適用は、OS の更新プログラムによってグローバルに行われるのではなく、パッケージ マネージャーによってアプリごとに行われます。

実際的な問題として、一方のスタックに対してコードを作成した場合、もう一方のスタックで実行することはできるのでしょうか。どのような問題でも似たような答えになりますが、状況によりけりです。使用する API が両方のプラットフォームに実装されていれば、.NET Core でも .NET Framework でもコードが実行されるように比較的簡単に調整できます。ただし、実行環境に依存するコードや、片方のスタックがサポートしない API (XAML ベースの UI を操作するライブラリなど) を使用しているコードを、両方のスタックで実行することはできません。コマンドライン ツール (bit.ly/1Sd8oIK、英語) や Visual Studio の拡張機能 (bit.ly/1LqX0aF、英語) として使用できる .NET Portability Analyzer は、.dll ファイルを分析し、.NET Framework から .NET Core にコードをどの程度移植できるかを示すレポートを生成します。移植に役立つツールは、今後さらにリリースする予定です。

コマンド ライン: .NET Core のエントリ ポイント

.NET Core には、アプリ開発に使用する基本ツールセットが付属し、新たなツールや強化されたツールが用意されています。このツールセットを、.NET Core CLI (.NET Core コマンドライン インターフェイス) と呼びます。.NET Core の他の部分と同様、.NET Core CLI もオープン ソース (GitHub.com/dotnet/cli、英語) で、開発作業に密接に関係するオープン ソース コミュニティの運営が活発に行われています。

新しいツールセットが導入されたのには、いくつか理由があります。1 つは、.NET Core が対象とする全プラットフォームの主要開発シナリオをサポートする必要があるためです。多種多様なプラットフォームのセットが考えられますが、どのプラットフォームの開発者でもコマンドライン エクスペリエンスは基礎として理解しています。つまり、コマンドラインであれば、各種プラットフォームに既定で組み込まれています。

ロジックを拡張する場合、サポート対象のプラットフォーム全体で同じ UX をサポートすることを考えます。Linux、Windows、OS X 間でUX を移植でき、ツール、各プラットフォームの構文やセマンティクスを学び直す必要がないのが理想です。コマンドラインであれば、どのプラットフォームでも同じものを使用できます。使用パターンは変わらず、構文も同じです。

複数のプラットフォームに 1 つのツールセットを使用するという考え方は、高度なツールの Visual Studio Code と Visual Studio にも当てはまります。こうした高度なツールは .NET CLI を基盤に階層化され、こうした階層化を利用して、.NET Core プロジェクトを将来に向けてサポートしていく予定です。つまり、Visual Studio で .NET Core アプリをビルドすると、ビルドの実行に .NET CLI ツールが呼び出されます。

.NET Core コマンドライン インターフェイスを試す

.NET Core CLI を最も簡単に始めるには、入門ガイド (aka.ms/dotnetcoregs、英語) に従います。簡単に言えば、プラットフォームに合わせてインストーラーをダウンロード (Ubuntu の場合は新しい apt-get フィードを登録) してツールをインストールするだけで、準備は完了です。インストーラーが、サポート対象の全 OS のシステム PATH にインストール フォルダーを設定し、CLI に必要な他のすべての環境変数を設定します。

その後、コマンド (別称「動詞」) を渡してドライバー "dotnet" を呼び出すことで開始できます。ドライバーは、コマンドでの引数の受け渡しと、コマンドの実行を担当します。本稿執筆時点で CLI パッケージに含まれるコマンドは図 2 のとおりです。もちろん、本稿が公開されるまでにはマイクロソフトが生産性向上用コマンドを追加していても不思議ではありません。

図 2 現在使用できる一般的な .NET CLI コマンド

コマンド 説明
dotnet new 言語に C# を使用して、クラス ライブラリまたはコンソール アプリ向けに有効なプロジェクトを初期化します。
dotnet restore 指定したプロジェクトの project.json ファイルで定義されている依存関係を復元します。通常、依存関係とはアプリで使用する NuGet パッケージです。
dotnet build コードをビルドします。このコマンドは、プロジェクトの中間言語 (IL) バイナリを生成します。プロジェクトがコンソール アプリの場合、生成される出力は、すぐに実行できる実行可能ファイルです。既定では、build コマンドは、コマンドが呼び出されたディレクトリの bin ディレクトリに、ビルド済みのアセンブリと実行可能ファイル (該当する場合) を出力します。
dotnet test 優秀なツールは、必ずテストを実行できるようになっています。このコマンドは、project.json ファイルで指定できるランナーを使用して、一連のテストを実行できるようにします。現在サポートされているテスト ランナーは、xUnit と NUnit です。
dotnet publish ターゲットのコンピューターで実行するためにアプリを公開します。
dotnet pack pack コマンドは、プロジェクトを NuGet パッケージにパッケージ化します。出力される一連の nupkg ファイルは、フィードにアップロードするか、ローカル フォルダーをオーバーライドすることによって復元操作で使用されます。
dotnet run run コマンドは、アプリをコンパイルして実行します。このコマンドで実行される操作は、Ctrl キーを押しながら F5 キーを押したときの操作と同じと考えられます。Visual Studio を使用しない点のみが異なります。

パッケージに含まれているコマンドの他にも、project.json でツールとしてコマンドを追加しておくと、コマンドを復元できます。こうしたコマンドは NuGet パッケージにパッケージ化され、使いやすく、理解しやすい優れた拡張モデルが実現されます。

まとめ

.NET Core を理解し、クロスプラットフォームで動作する .NET コードを作成する気になっていただけましたか。新しいスタックの .NET Core は、従来の .NET Framework では実現していない便利な機能を提供します。.NET CLI でも、開発者エクスペリエンスの基礎となり、Visual Studio や Visual Studio Code などの他のツールに統合できる、すばらしいコマンド ライン エクスペリエンスが導入されます。

最後に、マイクロソフトは開発者の手元に .NET Framework 用に作成した多くの資産があることを理解しています。こうした資産も .NET Framework の進化と共に引き続き成長していくことを願っています。マイクロソフトは、.NET Framework と .NET Core が両スタックの強みを生かしたシステムに共存する状況を思い描いています。

こうした状況を詳しく理解し、それにかかわっていくであろう方のために、出発点となる場をいくつか紹介します。

マイクロソフトは、他にも多くの .NET オープン ソース プロジェクトに取り組んでいます。そうしたプロジェクトに関心がある方は、.NET に関連するオープン開発やコラボレーションをの発展を目指す独立組織、.NET Foundation について確認してください。マイクロソフトは、Xamarin、Umbraco、Salesforce、.NET コミュニティなどと共に、.NET Foundation にいくつかプロジェクトを提供しています。.NET Foundation 自体と参加については、dotNetFoundation.org/projects (英語) を参照してください。


Surupa Biswas は、マイクロソフトで .NET チームのプログラム マネージャーを務めています。システムとプログラミング言語理論をこよなく愛し、友人と夜遅くまで同時実行モデルについて議論を交わすこともあります。彼は、あらゆるシステムのランタイム動作を型システムで表現し、人類が論理的思考をさらに高めることのできる日が来ることを願っています。連絡先は、phcart@microsoft.com (英語のみ) です。

Zlatko Knezevic は、マイクロソフトで .NET チームのプログラム マネージャー (PM) を務めています。2005 年にマイクロソフトに入社した後は、まず開発者エバンジェリストとして CEE に勤務してから、SQL Server の PM に就任しました。そこでは、コア エンジンへの新しいインデックスの追加から、ビッグ データやデータ検出などを扱う高度なサービスの構築まで、広範な取り組みに携わりました。2015 年、PM として .NET チームに加わってからは、.NET Core のクロスプラットフォーム エクスペリエンスに従事しています。連絡先は、Zlatko.Knezevic@microsoft.com (英語のみ) です。

この記事のレビューに協力してくれたマイクロソフト技術スタッフの Immo Landwerth および .NET Core and Framework Program Management チームに心より感謝いたします。