macでC#のWebサーバ開発(準備編)

最近Windows以外でのC#サーバーサイド開発ができないかを考えております。

.NET Coreを使えばmacやLinuxでもC#で開発できるとのことなので、
まずは手元のmacbookでローカル開発する為の方法を調べて試してみました。

今回の記事では簡単なサーバとして動くところまでの手順と、
開発に使用するエディタの機能拡張について記載していきます。

# C＃とは

マイクロソフトが2002年にリリースしたプログラミング言語です。
主にWindowsの.NET Framework上で動作する言語として知られているが、CLI準拠のMonoや2015年11月にリリースされた.NET Coreを使えば、Mac OS XやLinux上でも動作させることが可能。
例えば、ゲームエンジンのUnityではMonoが使用されており、Window・Mac上でC#を使い開発することができています。
Visual Studio 2015からはXamarinが統合され、C#でiOSやAndroid向けの開発ができるようになっています。
つまりC#を使用できれば、PCの主要3プラットフォーム(Windows,Mac OS X,Linux)だけでなく、主要な携帯デバイス(Windows Phone,iOS,Android)向けの開発までもできるということです。

2〜3年ごとに大きなアップデートがされており、最新ではC#6.0が2015年7月にリリースされています。
C#3.0から導入されたLINQは生産性向上に貢献しており、他の言語向けにも実装がされています。

# 開発環境

一般的にはVisual Studioと組み合わせて開発されることが多いです。
Visual StudioとC#は密接に連携しており、自動補完機能やデバッグ機能も充実しており生産性向上に貢献してます。
2015年4月にはMac OS XやLinux上でも動作するVisual Studio Codeがリリースされており、Visual Studioほど高機能ではないですが、自動補完機能やデバッグ機能を使用することができます。

ライブラリーの追加はNuGetを使うことで簡単に導入することができます。

# .NET Coreのインストール
## インストール前の準備
```shell-session
% brew install openssl                                                                                                                                               [17:59:45]
==> Downloading https://homebrew.bintray.com/bottles/openssl-1.0.2j.el_capitan.bottle.tar.gz
######################################################################## 100.0%
==> Pouring openssl-1.0.2j.el_capitan.bottle.tar.gz
==> Using the sandbox
==> Caveats
A CA file has been bootstrapped using certificates from the system
keychain. To add additional certificates, place .pem files in
  /usr/local/etc/openssl/certs

and run
  /usr/local/opt/openssl/bin/c_rehash

This formula is keg-only, which means it was not symlinked into /usr/local.

Apple has deprecated use of OpenSSL in favor of its own TLS and crypto libraries

Generally there are no consequences of this for you. If you build your
own software and it requires this formula, you'll need to add to your
build variables:

    LDFLAGS:  -L/usr/local/opt/openssl/lib
    CPPFLAGS: -I/usr/local/opt/openssl/include
    PKG_CONFIG_PATH: /usr/local/opt/openssl/lib/pkgconfig

==> Summary
🍺  /usr/local/Cellar/openssl/1.0.2j: 1,695 files, 12M

% ln -s /usr/local/opt/openssl/lib/libcrypto.1.0.0.dylib /usr/local/lib/

% ln -s /usr/local/opt/openssl/lib/libssl.1.0.0.dylib /usr/local/lib/
```

## .NET Core SDKのインストール
[Microsoftの公式サイト](https://www.microsoft.com/net/download)よりmac OS向けの.NET Core SDK Installerをダウンロードしてインストールする。

**zshを使用している場合**
dotnetコマンドが使えないので下記を実行する。

```shell-session
% ln -s /usr/local/share/dotnet/dotnet /usr/local/bin
```

## プロジェクトの初期化

```shell-session
% mkdir sampleapp

% cd sampleapp

% dotnet new                                                                                                                                                         [18:41:44]

Welcome to .NET Core!
---------------------
Learn more about .NET Core @ https://aka.ms/dotnet-docs. Use dotnet --help to see available commands or go to https://aka.ms/dotnet-cli-docs.
Telemetry
--------------
The .NET Core tools collect usage data in order to improve your experience. The data is anonymous and does not include commandline arguments. The data is collected by Microsoft and shared with the community.
You can opt out of telemetry by setting a DOTNET_CLI_TELEMETRY_OPTOUT environment variable to 1 using your favorite shell.
You can read more about .NET Core tools telemetry @ https://aka.ms/dotnet-cli-telemetry.
Configuring...
-------------------
A command is running to initially populate your local package cache, to improve restore speed and enable offline access. This command will take up to a minute to complete and will only happen once.
Decompressing 100% 3014 ms
Expanding 100% 12228 ms
Created new C# project in /Users/XXXX/_cs/sampleapp.
```

## プロジェクトの実行

```shell-session
% dotnet restore                                                                                                                                                     [18:44:31]
log  : Restoring packages for /Users/a12104/_cs/sampleapp/project.json...
log  : Writing lock file to disk. Path: /Users/XXXX/_cs/sampleapp/project.lock.json
log  : /Users/XXXX/_cs/sampleapp/project.json
log  : Restore completed in 989ms.

% dotnet run                                                                                                                                                         [18:45:14]
Project sampleapp (.NETCoreApp,Version=v1.0) will be compiled because expected outputs are missing
Compiling sampleapp for .NETCoreApp,Version=v1.0

Compilation succeeded.
    0 Warning(s)
    0 Error(s)

Time elapsed 00:00:01.5033355


Hello World!
```

# ASP.NETの設定
## Kestrel HTTP serverパッケージの追加

dependenciesに `"Microsoft.AspNetCore.Server.Kestrel": "1.0.0"` を追記する

```json:project.json
{
  "version": "1.0.0-*",
  "buildOptions": {
    "debugType": "portable",
    "emitEntryPoint": true
  },
  "dependencies": {},
  "frameworks": {
    "netcoreapp1.0": {
      "dependencies": {
        "Microsoft.NETCore.App": {
          "type": "platform",
          "version": "1.0.0"
        },
        "Microsoft.AspNetCore.Server.Kestrel": "1.0.0"
      },
      "imports": "dnxcore50"
    }
  }
}
```

```shell-session
% dotnet restore
```

## リクエストのハンドリング処理を追加

```csharp:Startup.cs
using System;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;

namespace aspnetcoreapp
{
    public class Startup
    {
        public void Configure(IApplicationBuilder app)
        {
            app.Run(context =>
            {
                return context.Response.WriteAsync("Hello from ASP.NET Core!");
            });
        }
    }
}
```

## Webホスト起動処理を追加

```csharp:Program.cs
using System;
using Microsoft.AspNetCore.Hosting;

namespace aspnetcoreapp
{
    public class Program
    {
        public static void Main(string[] args)
        {
            var host = new WebHostBuilder()
                .UseKestrel()
                .UseStartup<Startup>()
                .Build();

            host.Run();
        }
    }
}
```

## Webアプリケーションの起動

```shell-session
% dotnet run
```

ブラウザで `http://localhost:5000` にアクセスすると、下図のように表示されます。

![ブラウザでの実行画面](https://qiita-image-store.s3.amazonaws.com/0/43800/8805024d-fbee-2afd-8d18-589b31101a45.png)


# エディタの機能拡張
## Visual Studio Code
### C＃
https://marketplace.visualstudio.com/items?itemName=ms-vscode.csharp
.NET Core向けの開発ツール
シンタックスハイライトやIntelliSense、定義箇所へ移動、すべての参照を検索などのサポート

### Spelling and Grammar Checker
https://marketplace.visualstudio.com/items?itemName=seanmcbreen.Spell
失敗の検出と修正方法のサジェスト

### .Net Core Project Manager (Nuget)
https://marketplace.visualstudio.com/items?itemName=ksubedi.net-core-project-manager
NuGetパッケージの管理