C#でまともなアプリ開発を行うために

# はじめに
C#は「Windowsでしか開発出来ない言語」などクローズドなイメージから一転し、.NET Coreの誕生によって様々なことが出来るようになりました。最近では[okazuki](https://qiita.com/okazuki)さんの[C# で出来ること一覧](https://qiita.com/okazuki/items/e3a8e23f9ac2a10d8fde)が大きな反響を呼び、C#であらゆるアプリが作れることを多くの方に知ってもらえたかと思います。C#のよさを知ってもらうことは嬉しい限りではありますが、他言語をやってきた身としてはC#を取り巻くエコシステムの情報が少ないと感じることが多く、新たに参入される方にとって抵抗があるのも事実だと思います。この記事では**まともなアプリ開発**を行うために必要なエコシステムなどご紹介し、C#でも快適に開発出来ることを知ってもらえれば嬉しいです。筆者はWEB開発を主としているので、WEB寄りな話が多くなる可能性がありますがご了承下さい。

# 「まとも」とは？
タイトルにも書いた**まとも**なアプリ開発とは、**一定の品質を担保する仕組み**で開発出来ることです。具体的には

- 開発環境が特定のOSに依存しないこと
- 環境構築が容易であること
- 一定の品質を満たすことをCIで確認出来ること
- コードフォーマット
- 静的解析
- テスト（カバレッジが正しく検知出来ること）


です。また個人的には「**OSS（無料）であること**」を入れたいなと思っています。やはり、有料なものに比べ、情報量の多さとブラックボックスに包まれていない（議論されている）状態であることは、開発者にとって有益であると思うからです。

# 前提
C#の開発では基本的に[Visual Studio](https://visualstudio.microsoft.com/ja/downloads/)で完結出来ることが多いですが、**まとも**な開発をする上で特定のOSに依存しないことは絶対条件なので、この記事はLinux、Macで使うことを前提にご紹介します。もちろん、Windowsでも利用出来るものを選定しています。また、各ライブラリは詳しくは説明しません。

# 開発環境が特定のOSに依存しないこと
一般的にはVisual Studio、Visual Studio Codeが多いですが、特定のエディタ、IDEには依存しないので好きなエディタで開発することが出来ます。ですが、流石にvim、Emacsを使うような玄人は見たことがありませんが、開発は出来ます。

[Visual Studio](https://visualstudio.microsoft.com/ja/)

特定のOS関連ではありませんが、インストーラーを用いて.NET Coreをインストールする場合にOSのロケール値がセットされてしまうので、`en-us`に設定することをおすすめします。C#で開発するにあたって、情報の少なさを痛感することが多いので、より検索結果がヒットする英語に設定しておくことは重要だと思います。なので英語を読めなければいけないということではなく、スムーズに開発するための手段だと思ってもらえると嬉しいです。

```bash
# fishの例
set -x DOTNET_CLI_UI_LANGUAGE en-us
```

[dotnet CLIの環境変数](https://docs.microsoft.com/ja-jp/dotnet/core/tools/dotnet#environment-variables)

# 環境構築が容易であること
環境構築を容易にするために、まずはコンテナ化が挙げられると思います。MSの公式にコンテナ化のチュートリアルが載っているので、比較的簡単にコンテナ化することが出来ます。

[チュートリアル: NET Core アプリのコンテナー化](https://docs.microsoft.com/ja-jp/dotnet/core/docker/build-container?tabs=windows)


# 一定の品質を満たすことをCIで確認出来ること
一定の品質を保つためには、第三者に自分のコードを見てもらうこと、つまりコードレビューが必須です。しかし、人間は愚かなので必ずミスが発生します。そのため、最低限は機械的にチェックする仕組みを導入し、人間の考えることを極力減らすことが重要だと思います。CI上でチェックするためにCLIでフォーマット、静的解析、テストを利用出来ることは絶対条件です。.NET Core 2.1から導入された[.NETツール](https://docs.microsoft.com/ja-jp/dotnet/core/tools/global-tools)によって、今までCLIで操作出来なかったものが使えるようになりましたので、後述するツールは全てCLI上で操作出来るものを紹介します。CIに関してはGithub Actions、CircleCI、CodeBuildなどお好きなCIを選定していただけばと思います。筆者は自分のプロダクトにはGithub Actionsを利用していますので、ご参考になれば幸いです。

[GitHub Actionsで.NET CoreアプリをAzureにデプロイする](https://qiita.com/ikuosaito1989/items/1baf18c739d332f41411)

# コードフォーマット
## dotnet-format
<img width="300px" alt="dotnet-format" src="https://user-images.githubusercontent.com/9797472/61659851-6bbdc880-ac7d-11e9-95f7-d30c7de1a18a.png">
[dotnet-format](https://github.com/dotnet/format)

公式の.NET Platformから出ているフォーマットツールです。[.NETツール](https://docs.microsoft.com/ja-jp/dotnet/core/tools/global-tools)で利用出来ます。デフォルトでも利用出来ますが.editorconfigを設定することも出来ます。

**グローバルインストール**
プロジェクト毎に適用する場合は`-g`は不要です。

```bash
$ dotnet tool install -g dotnet-format
```

**実行**

```bash
$ dotnet-format <project>
```
# 静的解析

## Roslynator
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/496802/ce58a413-baa9-a9d6-1c38-cb3967931091.png)

[Roslynator](https://github.com/JosefPihrt/Roslynator)

Roslyn[^1]を利用した静的解析ツールです。StyleCop、FxCopとC#における静的解析ツールはいくつかありますが、無償[^2]でCLIで提供されている唯一のツールです。さらにVSCodeの拡張もあります。まだまだ開発途上という感じではありますが、活発に開発されているので伸びしろもあると思います。

**インストール**

```bash
$ dotnet add package Roslynator.Analyzers
$ dotnet add package Roslynator.CodeAnalysis.Analyzers
$ dotnet add package Roslynator.Formatting.Analyzers

# .NETツール
$ dotnet tool install Roslynator.DotNet.Cli
```

.NETツールに関して、ローカルインストール（`-g`オプションを付けない）でないとCIで利用出来ないので、導入は[こちら](https://qiita.com/nogic1008/items/ce2dec260aa31bf205d8)を参考にして下さい。


**診断**
ビルド後に診断しないと正しい結果が出ないのでご注意下さい。

```bash
# 診断
$ dotnet roslynator analyze
# 修正
$ dotnet roslynator fix
```

## StyleCopAnalyzers
![image.png](https://avatars3.githubusercontent.com/u/13452629?s=200&v=4)



[StyleCopAnalyzers](https://github.com/DotNetAnalyzers/StyleCopAnalyzers)

StyleCopの後身プロジェクトで、今なお活発に開発されているプロジェクトです。しかし、CLIがなくIssueにも挙がっていたのですが、開発されることはなさそうな雰囲気です。

[CLI?](https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/2571)

[rookx](https://qiita.com/rookx)さんが作成した[StyleCopAnalyzers.CLI](https://github.com/rookxx/StyleCopAnalyzers.CLI)はStyleCopAnalyzersをCLIとして利用することを想定されているので、現在StyleCopAnalyzersを使われている方は使ってみるのはいかがでしょうか？

# テスト

## xUnit
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/496802/ca9aad02-ffc1-ba58-9644-219633920698.png)

[xUnit](https://github.com/xunit/xunit)

nUnit、mstestなど様々なテストフレームワークが存在しますが、現在においてxUnitが一番メジャーかなと思います。

**実行**
カバレッジを収集し、閾値を100%にする

```bash
dotnet test /p:CollectCoverage=true　/p:Threshold=100
```

**テストレポートを出力する**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/496802/b0c4eda0-21be-69ed-a8f4-f600ffefafc3.png)

カバレッジが通っているか確認したい場合はレポートに出力することが出来ます。

- reportgeneratorインストール

[ReportGenerator](https://github.com/danielpalme/ReportGenerator)というツールを用いて、カバレッジを可視化出来るようにします。

```bash
dotnet tool install -g dotnet-reportgenerator-globaltool
```

- カバレッジライブラリをインストール

```bash

$ dotnet add package coverlet.collector
$ dotnet add package coverlet.msbuild
```

- テスト実行＆レポート化

```bash
$ dotnet test /p:CollectCoverage=true /p:CoverletOutput=result/ /p:CoverletOutputFormat=lcov /p:Threshold=100
$ reportgenerator -reports:./result/coverage.info -targetdir:./result/ start ./result/index.htm
```

こちら簡単にですが、プロジェクトを作成しましたので興味ある方はご覧いただければと思います。

https://github.com/ikuosaito1989/.netcore-unittest

# まとめ
最近になり、やっと自分の中で納得する**一定の品質を担保する仕組み**を構築することが出来ました。おそらく遅れをとっていた理由として、OSSになったのが最近であること、C#だけが前に進み、周辺ツールが先を行くC＃に追いつけない状況が続いたことが原因だと思います。C＃で作れないものはないと断言出来るほど、幅広い範囲を網羅してるので周辺ツールには目を瞑ってましたが、OSSで議論されながらより洗練されたライブラリが普及し、ディファクトスタンダードとなれば今まで以上にC#という選択肢が増えると思っています。なによりも、静的型付け言語なのに、品質を保つ仕組みを構築する情報が少なさが改善されたことが個人的には嬉しく思います。

# 陳謝
ここまで読んで頂きありがとうございます。上級者のような口ぶりで紹介しましたが、筆者は個人サービスでC#を利用しているだけの趣味プログラマーです。.NETにまつわる情報をキャッチしているつもりですが、わからない部分や間違っていることもあると思いますので、お気軽にご指摘いただけると嬉しいです。


[^1]: [^1]: C#及びVisual Basic .NETのフリーかつオープンソースのコンパイラ・コード解析API
[^2]: [^2]: 有償であればReSharperが利用出来るそうです。@karuakunさんありがとうございます🙇‍♀️