1

I develop a MAUI app solely for Windows. I want it to check on start, if a specific table in a database exists. I have a separate class that manages the database access and inject it via Dependency Injection.

However since the LifecycleEvents are created within the builder I do not have access to that class via the usual DI style way. So how I can do this?

Here is my code so far:

public static class MauiProgram
{
    public static MauiApp CreateMauiApp()
    {
        var builder = MauiApp.CreateBuilder();
        builder
            .UseMauiApp<App>()
            .UseMauiCommunityToolkit()
            .ConfigureFonts(fonts =>
            {
                fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
                fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
            });
        builder.Services.AddTransient<MainPage>();
        builder.Services.AddTransient<MainPageViewModel>();
        builder.Services.AddSingleton<IDatabaseAccess, DatabaseAccess>();
        builder.ConfigureLifecycleEvents(events => events.AddWindows(windows => windows
            .OnLaunching((window, args) =>
            {
                var app = App.Current;
                using (var serviceScope = App.Current.Handler.MauiContext.Services.GetService<IServiceScopeFactory>().CreateScope())
                {
                    var dbAccess =  serviceScope.ServiceProvider.GetRequiredService<IDatabaseAccess>();
                    if (!dbAccess.DoesMappingTableExist())
                    {
                        dbAccess.InitializeDb();
                    }
                }
            })));

#if DEBUG
        builder.Logging.AddDebug();
#endif

        return builder.Build();
    }
}

This does not work, because during runtime var app = App.Current is null. Same goes for the windows parameter, so I get a NullReferenceException.

AracKnight
  • 357
  • 5
  • 18

1 Answers1

2

OnLaunching is too early. Change it to a later event, OnLaunched (or OnWindowCreated):

    builder.ConfigureLifecycleEvents(events => events.AddWindows(windows => windows
        .OnLaunched((window) =>
        {
            var app = App.Current;   // Has a value now.
            ...
        }

If you really need access in .OnLaunching, see https://stackoverflow.com/a/76548416/199364, for an alternative way to get at service provider, that does not rely on App.Current.

ToolmakerSteve
  • 18,547
  • 14
  • 94
  • 196