.netのDI(Dependency Injection)は指定方法によって、その有効期間が異なる。
Blazorを使って、その有効期間を見ていこう。
まず、以下のようなクラスを用意する。
public class SingletonClass {
public int Count { get; set; }
public EventHandler? SingletonEvent { get; set; }
public void BubbleSingletonEvent(object? sender, EventArgs e) {
if (SingletonEvent != null) {
SingletonEvent.Invoke(sender,e);
}
}
}
public class ScopedClass {
public int Count { get; set;}
}
public class TransientClass {
public int Count { get; set;}
}
これらのクラスをサービスとして登録
・・・
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddRazorComponents()
.AddInteractiveServerComponents();
// Singleton
builder.Services.AddSingleton<SingletonClass>();
// Scoped
builder.Services.AddScoped<ScopedClass>();
// Transient
builder.Services.AddTransient<TransientClass>();
・・・
BlazorサンプルのCounterコンポーネントで、これらをInject
@page "/counter"
@rendermode InteractiveServer
@inject SingletonClass sic
@inject ScopedClass scp
@inject TransientClass trn
<PageTitle>Counter</PageTitle>
<h1>Counter</h1>
<p role="status">Current count: @currentCount</p>
<p role="status">Singleton: @sic.Count</p>
<p role="status">Scoped: @scp.Count</p>
<p role="status">Transient: @trn.Count</p>
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
@code {
private int currentCount = 0;
protected override void OnInitialized() {
// Singletonインスタンスへイベントハンドラを設定
sic.SingletonEvent += (sender,e) => this.InvokeAsync(this.StateHasChanged);
}
private void IncrementCount()
{
// それぞれインクリメント
currentCount++;
sic.Count++;
scp.Count++;
trn.Count++;
// Singletonインスタンスのイベントを発生させる
sic.BubbleSingletonEvent(this,new EventArgs());
}
}
実行すると・・・
このように、Singleton,Scopedの場合は、ページ遷移しても、インスタンスが保持されるが、Transientの場合はページ遷移すると、新しいインスタンスが作成される。
また、Singletonの場合はアプリケーション全体でSingletonとなるので、別インスタンスでも共有される。
この例では、Singletonにイベントハンドラを設定して、ボタンクリック時にイベントを発生させているため、別インスタンスでボタンがクリックされた場合、Singletonのカウントがアップされて表示される。
DIの動作が気になったので、メモ。
このサンプルだと、DIというかなんというかInjectionする意味が無いw
まぁ、有効期間を比べるだけのサンプルなので…