Dependency Injectionとは
Dependency InjectionとはDIとも呼ばれていて日本語で依存性の注入とも訳されています。
私たちは普段AのクラスにBクラス内のメソッドを使うとき、AクラスはBクラスをnewしてBクラスを引き出し、そのメソッドを呼び出している。
このクラス通しの関係を依存関係にあるといい、普段newしている場合はAクラスが別のクラスを引き出しているので注入とは言えません。
注入するということは外部からこのクラスを使いなさいとAクラスに与えることで、そのメソッドを呼び出す形にしています。
これによりクラスの疎結合が担保されます。
メリット
主な利点はクラス同士の依存関係の結合を減らすことです。
各クラスがどのように実装されているかを知り、維持する必要がないため、再利用性、テスト性、保守性が向上します。
これにより機能を利用する側(A)と機能を与える側(B)のアクセスがより柔軟になります。
.NET MAUIでの実装
.NET MAUIではデフォルトでDIコンテナ機能がついているので、簡単にDIができるようになり、大規模開発でもクラスの柔軟なアクセスができるようになります。
今回は、ViewModelをサンプルアプリに作成し、そこで作り出したプロパティをDIによりMainPageに表示させる方法で解説します。
ViewModelはこんな形
namespace Dependency
{
public class ViewModel
{
public string VMTitle { get; set; } = "Dependency Injection!!";
}
}
このVMTitleのプロパティをMainPageに入れたい
まずMauiProgram.csファイルにてDIをするためのコンテナを準備します。
public static class MauiProgram
{
public static MauiApp CreateMauiApp()
{
var builder = MauiApp.CreateBuilder();
builder
.UseMauiApp<App>()
.ConfigureFonts(fonts =>
{
fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
});
//↓たったこれを追加するだけでViewModelのDIコンテナが作成できる。
builder.Services.AddSingleton<MainPage>();//最初の画面であるメインページ(クラスA)
builder.Services.AddSingleton<ViewModel>();//プロパティを注入するViewModelクラス(クラスB)
//またこんな形に省略もできる
builder.Services.AddSingleton<MainPage>() //;がいらない
.Services.AddSingleton<ViewModel>();//最後に;
#if DEBUG
builder.Logging.AddDebug();
#endif
return builder.Build();
}
}
作り出したDIコンテナをMainPageにコンストラクタとして注入するだけです。
そして受け取る側MainPageにはコンストラクタとして受け取る形で注入されます。
public partial class MainPage : ContentPage
{
//↓ViewModelをコンストラクタとして注入している
public MainPage(ViewModel vm)
{
InitializeComponent();
BindingContext= vm;//←注入したコンストラクタをバインディングコンテキストに代入
}
}
MainPageのXamlではLabelのテキストに注入されたプロパティ"VMTitle"をバインディングします。
<Label Text="{Binding VMTitle}"//←バインディング
SemanticProperties.HeadingLevel="Level2"
SemanticProperties.Description="Welcome to dot net Multi platform App U I"
FontSize="18"
HorizontalOptions="Center" />
AddSingletonとAddTransient
AddSingletonとAddTransientの違いですが、これはnewしてインスタンスが1回切りの呼び出しにするか複数回呼び出すかの違いになる。
例えば一回きり呼び出されたら変更がないMainPageやListViewなどforの前にインスタンスがnewされていたようなページにはAddSingletonとなり、
遷移元が送ってくるデータによって、毎回画面の表示が変わるナビゲーション先のページなどはTransientの方が好ましい形となる。
以下Microsoft公式の説明
名前 | 説明 |
---|---|
AddSingleton | アプリケーションの存続期間中残るオブジェクトの単一のインスタンスを作成します。 |
AddTransient | 解決中に要求されたときにオブジェクトの新しいインスタンスを作成します。一時オブジェクトには事前定義された有効期間はありませんが、通常はホストの有効期間に従います。 |
さいごに
今回作成した簡単なサンプルアプリだとDIの利点が全くないように見えますが、規模が大きくなるごと、処理が複雑になるごとにこのDependency Injectionの重要性がわかってくるかと思います。
かなり簡単に実装できると思いますので、ぜひ使ってみてください。