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


はじめに

Blazorいいよね…
けどまだ日本語資料少ないからMS公式見るか英語ページ頻繁に見に行かないと駄目.
なので自分用メモも兼ねて記事書きます.

Blazor+DIで構築していきます.

準備

先ずはBlazorのテンプレートのインストールから.
CLIで以下を入力.

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

Visual Studio 2019にて新しいプロジェクトの作成にBlazorアプリの項目が追加されているはずです.
後はプロジェクトを作成するだけ.

DI

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

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

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.具象クラスの実装

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

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

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.csConfigureServicesに以下のコードを追加します

   services.AddTransient<IDataService,UserService>();

Transient(サービス毎に新しいインスタンスを取得)もしくは
Singleton(同一サービス単一インスタンス)
での指定が可能です.

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

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 と記述するだけでビハインドからデータを引っ張ってこれます.

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

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/>とするだけでリスト形式のコンポーネントが描画されます.

コードがスッキリする上に変数参照@変数名だけで持ってこれるし快適です.

あとがき

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

MSがどこまで力を入れるのかは疑問ではありますが,
Blazor WebAssemblyの正式版を5月にリリース予定等着実に開発を進めていっているようです.

流行ってほしいなぁ