さいきんの.NETのこととかNuGetとかCoreとかよく分からないよねーって話

Visual Studio 2017 RC が出たのでいろいろ遊んでみましたが、やばいですね！ちょっと変なことしようとするとすぐ変になったり動かなくなったりします！リリース前のアプリで遊ぶのめっちゃ楽しい……！

---
時代は.NET Coreですよ！

みたいに言われてたので、2017RC出たことだしそろそろ.NET Coreのことちゃんと調べるかーって思ったら、なんか予想以上にカオスなことになってたので、せっかくなので備忘録的に整理してみました。
昨日からの一夜漬けの知識量で錯綜しているネットの情報を漁りつつ書いてるので、何か間違いがあったら指摘してください。よろしくお願いします。

# .NETのなんかいろいろ用語集
Coreがどうのこうのとか.NETCoreが.NETでなんだかもうよく分からないので書いてあること片っ端から読んでおぼえた。.NET Coreについて調べるときぽろぽろ出てくる単語を片っ端から羅列してみたので、ちょっと読みづらいかもしれない。何か思いつく度に追記するかも。

### .NET Standard
.NETの基本的なAPIのセットのこと。
これをターゲットにライブラリを作ると、各プラットフォーム固有のAPIが一切使えない代わりに、
どのプラットフォームでも動作するポータブルなライブラリが作成できる。
以前あったPortable Class Library(PCL)の仕組みを一からちゃんと作りました的な枠組みと言えばいいのかな。
含むのはあくまでAPIの定義だけで、その実装はプラットフォーム側が提供する。C#でいう超巨大なinterfaceのようなものだとイメージすればいい。
当然ランタイムも含まないので、実行ファイルは作成できない。

### .NET Framework
.NETのWindowsプラットフォーム。Windowsに固有のAPIを多数搭載している。WPFもこのセットに含まれる。つまり、いつものやつ。どっとねっとふれーむわーく。
.NET StandardのAPIを実装しているので、.NET Standard向けに書かれたライブラリは無条件で使用できる。
例えば、net46はnetstandard1.3までをサポートしている。

### .NET Core
.NETの新しいプラットフォーム。クロスプラットフォームを前提に作られているので、
Windows/Mac/Linuxで動作するAppを作成できる。その代わり、OSなどプラットフォームに依存する機能は使えない。
.NET StandardのAPIを実装しているので、.NET Standard向けに書かれたライブラリは無条件で使用できる。
netcoreapp1.0はnetstandard1.6までのAPIをサポートしている。
.NET Coreと言うと普通はこのプラットフォーム全体のことを指すけど、プラットフォームのランタイム部分(== CoreCLR)を指して.NET Coreと言ったり、プラットフォーム互換の標準API(== .NET Standard)のことを指して.NET Coreと言ったりしてる場合があるので、文脈を読むチカラが必要。

### ASP.NET Core
.NET Coreプラットフォームのランタイム上で動くように作られたWeb関係のものひとまとめソリューション。.NET Frameworkの上でも動かせる。
以前までのASP.NETとの関係は、同じWebのソリューションであり、似たようなAPIやテンプレートエンジンを持っていること以外は全くの別物だと思っていい。
これからASP.NET Coreプロジェクトを新規で作るなら、.NET Coreをターゲットに作成するのが正解かも。

### Mono
まだ.NETがオープンじゃなかった時代から存在する、.NET Frameworkと互換なマルチプラットフォーム。
元々は.NETをMacとかLinuxでも動かしたくて作られたサードパーティ製の.NET Frameworkの移植で、それぞれのプラットフォームに向けて.NET Framework相当のセット(コンパイラ・基本クラスライブラリ・ランタイム)を提供している。
MacとかiOSに向けて.NETを書くときはこれ。今では、.NETのプラットフォームの一つとして肩を並べている。

### Xamarin
~~.NETのMacプラットフォーム。Macに依存する機能やUIに関するAPIを含む。~~ちょっと違った。
Monoのプラットフォーム上で動作する、クロスプラットフォーム開発を実現するための統合開発環境のようなもの。
iOSやAndroidのネイティブAPIをフルスペックでラップしたAPIライブラリや、各プラットフォーム間の差異を吸収し、ある程度共通のコードで記述できるGUIライブラリなどを提供している。
最初から一つのプロジェクトを複数のプラットフォームに展開することを目的とした、比較的上位レイヤをカバーするソリューション。
各対象プラットフォーム毎に名前がついてる。Xamarin.iOS、Xamarin.Mac、Xamarin.Androidなど。ちなみにXamarinは企業名でもある。
Microsoftとがっちゃんこして.NETの正式メンバーになった。独自で提供していたIDE、Xamarin Studioは2017でVisual Studio for Macとして生まれ変わった。

### CoreCLR
.NET Core Common Language Runtimeの略。
.NET Coreプラットフォームの一部で、実際の実行環境に相当するやつ。
.NET Coreプラットフォーム == CoreCLR + .NET Standard 1.6みたいに覚えておけばいい。

### CoreFx
.NET Coreの基本ライブラリの実装のこと。
.NET Frameworkでいう基本クラスライブラリ(BCL)みたいなやつ。
netstandard1.6のAPIをインターフェースだと見なしたとき、それのimplementsに相当。
.NET Core Appを実行する時に必要になる。

### NuGet
.NETのパッケージ管理のツール、またはそのインフラ。
自分のプロジェクトに「このパッケージを使うよ」って書いておくと勝手にダウンロードしたり準備してくれる。
インフラのNuGet(nuget.org)は、誰でも作ったライブラリやアプリをアップロードして、全世界に向けて公開できる。
どのパッケージがどのプラットフォームに対応しているかは、TFMとかいう各ターゲット名を短縮したような専用の表記で書かれる。
というか、nuget.orgのパッケージ個別ページにどのプラットフォームをサポートしてるのかくらい書いて欲しいんだけど。

### DNX(dnx/dnvm/dnu)
~~死にまし~~生まれ変わりました。
.NET Coreプラットフォームの前身。元々はASP.NETをクロスプラットフォームにするためのプロジェクトだった？
コマンドラインインターフェースでソリューションを管理するとか新しいことをいろいろ始めた先駆者。
今はプラットフォームは.NET Coreに、コマンドラインインターフェースはdotnetコマンドに受け継がれた。
DNXに関するWeb情報は、だいたい.NET Coreやdotnetコマンドのことだと読み替えれば大丈夫。
NuGetのTFMが汚染されまくったのはだいたいこいつのせい。

### .NET Platform
.NET Standardの前身。既に使われていない呼び名。
全ては.NET Standardになるのだ。
バージョンがv5.0とかv5.4みたいによく分からない数字なんだけど、これはそれぞれnetstandard1.0と1.4に対応している。だったはず。
.NET Frameworkがv4.6だからvNextは5.0だよねーって感じ？

### dotnetコマンド
.NET Coreプラットフォームに直接アクセスできるコマンドラインインターフェース。
dotnet-cli(.NET Core Command-Line Interface)とも呼ばれる。
今までVisual Studioからやってたビルド操作とかテストとかをコマンド叩いて直接動かせる。
Visual Studioが無くてもこれがあれば一応なんでもつくれる。
Visual Studio 2017が正式リリースされた頃には、おそらくこのツールに一切触らなくても、Visual Studio上の操作だけで完結できるようになってる……はず。

### project.json/.xproj
死にました。あ、いや、2017RCでようやく死にはじめたところです。
.NET Coreの発展途上で生まれた存在。.csprojを代替する予定だったもの。
今までの.csprojだと、MSBuildがWindowsに依存しててクロスプラットフォームつらいとか、プロジェクトファイルに何でもかんでも書くスタイルだと保守が大変だしUIがないとキビシイとかの問題が出ていたので、プロジェクトファイルの中身はソースファイルの管理とかの必要最低限にして、プロジェクトのメタデータは外出ししようぜ！みたいな流れが生まれた？
そして誕生したのが、ほとんど目印の役目しかない.xprojファイルと、プロジェクトメタデータを全部記述したproject.json。
そして、その後、紆余曲折を経て、なんか、廃止されることになりました。
.csprojに返り咲くとともに、project.json/.xproj構成でメリットがあった部分を.csproj側に取り込む方向に舵を取りました。
そして、2017RCでついに新しいカタチの.csprojがお披露目されることになったのでした。
Web上に多数存在するproject.jsonに関する情報は全て過去のものになった。つらい。

### NETStandard.Library
nugetパッケージの一つ。.NET StandardのAPIそのもの。
netstandardなライブラリを作成するときに必要。
コレを追加することで、netstandardのAPIを参照できるようになる。
API仕様をドキュメントとかではなくコードとそのパッケージで直接表現するっていうスタイル、わりと好き。
以前までのライブラリ作成プロジェクトで、mscorlib.dllとかを参照に追加するみたいなイメージに近い。

### Microsoft.NETCore.App
nugetパッケージの一つ。.NETCoreAppの実体。
netcoreappをターゲットにしている場合、まずコレを追加しないと始まらない。
NETStandard.LibraryがAPI参照だけなのと違って、こっちはちゃんと実装を持つ。

# netcoreapp1.0/netstandard1.0/net46/...みたいなやつの話
このわかるようでよく分からないターゲット名みたいなやつはなんなのか。
これはTarget Framework Moniker(TFM)というやつで、NuGetがターゲットプラットフォームを解釈する時に使うプラットフォームの短縮名。表記はちゃんと定まってるので、覚えなきゃダメなやつ。
開発途中の段階でいろいろ新しいのが増えては廃止されを繰り返してるせいで非常にカオスなことになっている。とてもとてもクソ。

## イマドキの使えるTFM

### `netstandard1.0` - 1.x
.NETの標準API仕様に準拠したライブラリAPI。
.NETStandardっていう規格に適合してますよって言う枠組みみたいなもの。
今ライブラリを作るならまずはこれ。

### `net46`/`net451`/...
Windowsにインストールされた.NET Frameworkの上で動くアプリケーション用のAPI。
いわゆる普通のC#の標準ライブラリセット。Windowsでのみ動く。
Windowsに関するAPIが全部使えるので、WPFアプリケーションとかはこれになる。

### `netcoreapp1.0`
標準APIのクロスプラットフォーム実装である.NET Coreの上で動くアプリケーション用API。
これは.NETCoreAppっていうフレームワーク名になる。__似たようなのに.NETCoreって言うのがあるけど、全くの別物なので注意。__
これで作ったアプリケーションはWindows/Mac/Linuxでそのまま動く。
GUIとかのプラットフォーム依存な機能は含まれない。

### `uap`
Universal Windows Platform(UWP)アプリケーション向けのAPI。
winのAPIを含んでいるらしい？ということは実質winの拡張なの？
.NET CoreのAPI(== netstandard)に沿ったWindowsデバイスのクロスプラットフォームアプリケーション。で、あってる？

### `xamarinios`/`xamarinmac`/`monoandroid`/...
Xamarin/Monoの各プラットフォームで使用できるAPI。
それぞれプラットフォーム固有のAPIを持つ。
Xamarinはコードの共有を念頭に置いてるので、PCLの定義にこの名前が含まれてるのをよく見かける。
でもこれからは、コードを共有するならnetstandard。だからね！

## イマドキじゃないけどまだ使えるTFM

### `win`
これって今も生きてるの？Windows RTのアプリケーション向けのAPI。
Windows8.1のストアアプリのやつ？使ったことないからよくわからない……
中身は.NET Core(netcoreappのベースAPI == netstandard) + Windows 8固有APIって感じらしい。

### `wp`
Windows PhoneのAPI。らしい。よくわからん。

### `wpa81`
Windows PhoneアプリケーションのAPI。wpとは何かが違うらしい。よくわからん。使う予定もない。他のこと全部調べ終わったら調べてみようか……。

### `portable-xxx-xxx-xxx-xxx`
複数のTFMを並べることで、同じDLLを複数のプラットフォームに向けられるもの。
各ターゲットのAPIの共通部分を抜き出して使うイメージ。
いわゆるPortable Class Library(PCL)のこと。
PCLは、もう、死にました。これからは.NETStandardを使いましょう。
汎用ライブラリを作るのにnetstandardにしないなんてありえないよねー(
あ、でもnetstandardは.NETFrameworkでいうv4.5未満はサポートしてないので、そこらへんのレガシーもサポート対象に含みたい時はportableを使うか、それぞれ名指しでサポートするしかない。

## 以下、イカレたメンバーのご紹介

### `netcore`
これはnetcoreappではない。もう一度。__これはnetcoreappではない__。
中身はwinと同じものらしい。つまり、WinRT。
どうしてnetcoreなんて名前を付けてしまったのか……。
たしかにwinのランタイムはnetcoreappの原型みたいなもんだけどさ……。
不幸しかない。

### `dotnet`
既に廃止されています。
.NETの標準APIを定義するやつ……つまり、今で言うnetstandardのこと。
なんで名前変えたんだっけ？バージョン表記がアレだったからかな……？

### `netstandardapp`
既に廃止されています。
.NETStandardでApp？？ってなったけど、これは.NETCoreAppのこと。netcoreappと同等。
断じてnetstandardではない。わかりづらすぎでしょ……。

### `dnx`/`dnxcore`
既に廃止されています。
dnxはnetに、dnxcoreはnetcoreappに、それぞれ統合されました。
といっても、NuGetにあるパッケージのターゲットにはまだまだ書かれているものも多いので、dnxってなんやねんってならないように覚えときましょう。
もう一度。dnxはnet、dnxcoreはnetcoreapp。

# おわり
Webの情報だと、開発中に登場して既に廃止された内容が普通に出てくるので非常に紛らわしい。しかもそれが名前も紛らわしかったりするともうしぬ。とてもつらい。でもなんとかイメージはつかんだぞ。たぶん。また何か追記するかも。