Blazor + DIでコンポーネントを作るまで

はじめに
---
Blazorいいよね…
けどまだ日本語資料少ないからMS公式見るか英語ページ頻繁に見に行かないと駄目.
なので自分用メモも兼ねて記事書きます.<br>
`Blazor`+`DI`で構築していきます.<br>

準備
---

先ずはBlazorのテンプレートの[インストール](https://docs.microsoft.com/ja-jp/aspnet/core/blazor/get-started?view=aspnetcore-3.1&tabs=visual-studio)から.
CLIで以下を入力.

```
dotnet new -i Microsoft.AspNetCore.Blazor.Templates::3.2.0-preview1.20073.1
```

`Visual Studio 2019`にて新しいプロジェクトの作成にBlazorアプリの項目が追加されているはずです.![8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/528662/05e70327-29a9-e4ca-1417-13f1bd4cf9f3.png)
後はプロジェクトを作成するだけ.


DI
---

DIとはなにかは調べてください(投げっぱ)<br>

1.DIサービスの実装
   `interface` 型のインターフェース`IHogeService`を定義します,今回は簡単に`getUsers`のみとします.
以下コード.

   ```c#:IHogeService.cs
    using Hoge.Class;
    using System.Threading.Tasks;
    using System.Collections.Generic;

    namespace Hoge.Model.Service
    {
        public interface IHogeService
        {
            Task<List<UserEntity>> getUsers();
        }
    }
   ```

2.具象クラスの実装
   
具象クラスを実装していきます.
適当にデータでっちあげて作ります.
以下コード.

   ```c#:UserEntity.cs
   namespace Hoge.Class
   {
       public class UserEntity
       {
           public int UserID { set; get; }
           public string UserName { set; get; }
           public uint Age { set; get; }
       }
   }

   ```

   ```c#:UserService.cs
    using System;
    using System.Linq;
    using System.Threading.Tasks;
    using System.Collections.Generic;
    using Hoge.Class;

    namespace Hoge.Model.Service
    {
        public class UserService : IHogeService
        {
            public Task<List<UserEntity>> getUsers()
            {

                return Task.FromResult(Enumerable.Range(1, 15).Select(index => new UserEntity
                {
                    UserID = 12345,
                    UserName = "hoge hoge",
                    Age = 5
                }).ToList());
            }
        }
    }
   ```

3.DIコンテナへサービスの追加
   `Startup.cs`の`ConfigureServices`に以下のコードを追加します

   ```
   services.AddTransient<IDataService,UserService>();
   ```
   `Transient`(サービス毎に新しいインスタンスを取得)もしくは
   `Singleton`(同一サービス単一インスタンス)
   での指定が可能です.

次にコンポーネントのビハインドを作っていきます
以下コード.

```c#:UserDataBase.cs
using System;
using System.Threading.Tasks;
using System.Collections.Generic;
using System.Linq;
using Microsoft.AspNetCore.Components;
using Hoge.Model;
using Hoge.Model.Service;

namespace Hoge.Model
{
    public class UserDataBase : ComponentBase
    {
        [Inject]
        private IDataService userDataService {set; get;}

        [Parameter]
        public List<Class.UserEntity> userData {set; get;}

        protected override async Task OnInitializedAsync()
        {
            userData = await userDataService.getUsers();
        }
    }
}
```
これでDIは終わり
あとは使いたいページで`@inherits Hoge.Model.UserDataBase` と記述するだけでビハインドからデータを引っ張ってこれます.

以下コンポーネント側コード

```c#:UserListComponent.razor
@inherits Hoge.Model.UserDataBase

@if (userData == null)
{
    <p> <em> Loading...</em> </p>
}
else
{
    <table class="table table-striped table-bordered table-responsive-xl">
        <thead>
            <tr>
                <th class="text-center" scope="col">No.</th>
                <th class="text-center" scope="col">ID</th>
                <th class="text-center" scope="col">名前</th>
                <th class="text-center" scope="col">年齢</th>
            </tr>
        </thead>
        <tbody>
            @foreach (var (userdata, index) in userData.Select((userData, index) => (userData, ++index)))
            {
                <tr>
                    <th class="text-center" scope="row">@index</th>
                    <td class="text-center">@userdata.UserID</td>
                    <td class="text-center">@userdata.UserName</td>
                    <td class="text-center">@userdata.Age</td>
                </tr>
            }
        </tbody>
    </table>
}
```

あとはコンポーネントを使いたい場所で`<UserListComponent/>`とするだけでリスト形式のコンポーネントが描画されます.<br>
コードがスッキリする上に変数参照`@変数名`だけで持ってこれるし快適です.

あとがき
---
今はライブラリの選択肢はあまり多くないし,日本語資料の少なさは言わずもがなですが,
コードが雑然としなくてとてもいいし何よりC#で書けるのが好き.

MSがどこまで力を入れるのかは疑問ではありますが,
Blazor WebAssemblyの正式版を5月に[リリース予定](https://www.publickey1.jp/blog/20/blazor_webassembly5blazorpwa.html)等着実に開発を進めていっているようです.

流行ってほしいなぁ