✨
MAUI で Page でコンストラクタ インジェクションをする方法
わかると、まぁそうだよねという内容なのですがわからないとハマる(というかハマった)のでメモっておきます。
MAUI では ASP.NET Core のような雰囲気でスタートアップ処理が記述できて、DI の機能も利用できるようになっています。MauiProgram
クラスの CreateMauiApp
メソッドで DI コンテナにクラスを登録したりできます。
MauiProgram.cs
using MauiApp9.Platforms;
namespace MauiApp9;
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");
});
// ここで DI コンテナに登録できる
builder.Services.AddSingleton(_ => MyGeolocator.Default);
return builder.Build();
}
}
そして、デフォルトのプロジェクトテンプレートで使われている Shell では画面遷移時に DI コンテナから Page のインスタンスを取得してくれるようになっているみたいで、Page に対してコンストラクタ インジェクションが出来るようになっています。
ただ、この機能を使うには以下のように ページクラスを DI コンテナに登録していないとダメ なので注意が必用です。
MauiProgram.cs
using MauiApp9.Platforms;
namespace MauiApp9;
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");
});
// ページもこういう風に登録する!
builder.Services.AddTransient<MainPage>();
builder.Services.AddSingleton(_ => MyGeolocator.Default);
return builder.Build();
}
}
これで以下のように Page のコンストラクタに引数を追加して、そこに DI コンテナからインスタンスを渡してもらえるようになります。素敵!
MainPage.cs
using MauiApp9.Platforms;
namespace MauiApp9;
public partial class MainPage : ContentPage
{
int count = 0;
private readonly IMyGeolocator _myGeolocator;
// コンストラクタで DI コンテナからインスタンスを受け取れる
public MainPage(IMyGeolocator myGeolocator)
{
InitializeComponent();
_myGeolocator = myGeolocator;
}
... 省略 ...
}
因みに DI コンテナに Page を登録していない状態でコンストラクタ インジェクションをしようとすると以下のように原因不明っぽいエラーで落ちます。(Windows の場合、他のプラットフォームは未確認)
もうちょっとわかりやすいエラーを吐いてほしい…。
ということでハマったのでメモでした。何時間か溶けた…。
Discussion