XXXコーディング規約

# はじめに
* 本資料は、XXXシステムのコーディング規約を記したものです。　
* WebAPIフレームワークはAPS.NET Coreを使用します。　
* Repository層は中規模開発のため軽量なEntityFramework Coreを使用します。　
* APS.NET Core標準の依存関係の挿入 (DI) ソフトウェア設計パターンを使用します。　

# 前提知識
[ASP.NET Core概要](https://docs.microsoft.com/ja-jp/aspnet/core/introduction-to-aspnet-core)  

[Entity Framework Coreの概要](https://learn.microsoft.com/ja-jp/ef/core/)

[ASP.NET Core での依存関係の挿入概要](https://docs.microsoft.com/ja-jp/aspnet/core/fundamentals/dependency-injection)

[単体テストの概要](https://learn.microsoft.com/ja-jp/aspnet/core/mvc/controllers/testing)

[C# のコーディング規則](https://docs.microsoft.com/ja-jp/dotnet/csharp/fundamentals/coding-style/coding-conventions)


# コーディング規約詳細
### コントローラ
1. ソースファイルは"Controllers"フォルダに格納して下さい。　
1. コントローラのコードは簡潔にし、できるだけビジネスロジックに委譲して下さい。　
1. DB操作は禁止します、DB操作が必要な場合はビジネスロジック経由で行って下さい。　
1. パラメータエラーの場合はArgumentExceptionを送出して下さい。　
    ```C#
    if(String.IsNullOrEmpty(userId))
    {
        throw new ArgumentException(userId, "NULLまたは空");
    }
    ```
1. ビジネスロジックを利用する場合は必ずコンストラクタで定義してください。（DI)
    ```C#
    private readonly UserService _userService;
    public UserController(UserService userServicec)
    {
        _userService = userService;
    }
    [HttpGet]
    public User GetUser(string userId)
    {
        if(String.IsNullOrEmpty(userId))
        {
            throw new ArgumentException(userId, "NULLまたは空");
        }
        return __userService.GetUser(userId);
    }
    ```
        
### ビジネスロジック
1. ソースファイルは"Services"フォルダ内に格納してください。　
1. 必ずインターフェースを定義して下さい。　
1. DB操作を行う場合は、必ずコンストラクタで定義して下さい。（DI)
    ```C#
    public class UserService
    {
        private readonly DBContext _db;
        public UserService(DBContext db)
        {
            _db = db;
        }
        public User GetUser(string userId)
        {
            return _db.Users.Where(x => x.UserId = userId).SingleOrDefault();
        }
    }
    ```
1. 他のビジネスロジックを利用する場合も必ずコンストラクタで定義してください。（DI)
    ```C#
    private readonly DBContext _db;
    private readonly CompanyService _companyService;
    public UserService(DBContext db, CompanyService companyService)
    {
        _db = db;
        _companyService = companyService;
    }
    ```
1. エラーは必ずBizExceptionを送出して下さい。 
    ```C#
    if(count == 0)
    {
        throw new BizException("カウントは0件です");
    }
    ```      
### モデル
#### View Model
1. コントローラで利用するモデルは"Models/ViewModels/コントローラ名"フォルダに格納して下さい。　
#### Business Model
1. ビジネスロジックで利用するモデルは"Models/ViewModels/ビジネスロジック名"フォルダに格納して下さい。　
#### Entity Model
1. DBアクセスで利用するモデルは、DBファーストで自動作成してください。　
1. 以下のコマンドで同期を行います。 
   ```
   dotnet ef dbcontext scaffold -f "Server=.\SQLEXPRESS;Database=XXX;persist security info=True;Integrated Security=true;MultipleActiveResultSets=True" Microsoft.EntityFrameworkCore.SqlServer -c DBContext -o Models/Entity
   ```
1. 上記コマンド実行後モデルは"Models/Entity"フォルダに格納されます。   

### 例外の集中管理
1. SystemException、Exceptionは集中管理するのでプログラム中でTryは行わないで下さい。 
1. ログ出力は集中管理で行いますのでプログラムでは行わないでください。 

### DI
1. 作成したビジネスロジックはStartup.DI.csに定義して下さい。　
    ``` C#
    //シングルトンのビジネスロジック
    services.Singleton<IUtil, Util>();
    
    //一般的なビジネスロジック
    services.AddTransient<IUserService, UserService>();
    ```

# 単体テスト詳細
作成中。

# 参考 XXXシステムフォルダ構成
XXXXX
│
├Controllers　※コントローラ
│ ├UserApi.cs
│
├Servicees　※ビジネスロジック
│ ├UserService.cs
│
├Models　※モデル
│ ├ViewModels
│ 　├UserView.cs
│ ├BusinessModels
│ 　├UserBiz.cs
│ ├Entity
│ 　├User.cs
│
├appsettings.json　※定義ファイル
│ ├appsettings.Prod.json
│ ├appsettings.Stg.json
│ ├appsettings.Developmemt.json
│
├Util　※ユーティリティ
│ ├Util.cs