Some example is needed for using the new version with dependency injection #43
-
The updated docs mention that this library (and associated) have been updated to support dependency injection. That's pretty great, but the problem is that once the native dotnet DI container is built it becomes immutable and can't be initialized asynchronously, at least in something like Maui. This creates a problem for applications that have many viewmodels using repositories that request data from Postgrest with, say, explicit clauses for the current user's UID, on pages that would require access to the current user object, or on pages that would like to subscribe to Realtime. I am probably missing something, but I can really only see two ways to solve this:
Option 2 doesn't seem intended, considering there was just a multi-project push to support dependency injection and is basically how I used the Supabase libraries prior to this update, just using the libraries Instance property instead of creating my own. It carried a big benefit though: I initialized Supabase early enough in the applications lifecycle that I could ensure it would be ready to determine where the application should take the user on open (logged in or out views). I'm sure I'm just missing something though, so some example of how this library is expected to be used and initialized now in a multiple-page, many-consumer application would be great. |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 2 replies
-
The async initialization pattern, to me, makes sense for services that are really only used in one or two places. The cost of possibly initializing them twice is not so great (usually). On the other hand, Supabase tends to be an application backbone, so it doesn't really make any sense to initialize it a ton of times. |
Beta Was this translation helpful? Give feedback.
-
@RedChops I have been using the Dependency injection model with Maui by specifying
static IServiceProvider? serviceProvider;
public static TService? GetService<TService>() => serviceProvider!.GetService<TService>();
public static MauiApp CreateMauiApp() {
// ...
builder.Services.AddSingleton(provider =>
new Supabase.Client(
supabaseUrl,
supabaseKey,
new SupabaseOptions
{
AutoRefreshToken = true,
AutoConnectRealtime = true,
SessionHandler = new SupabaseSessionHandler()
}
));
builder.Services.AddSingleton(provider => new AppStateService(provider.GetRequiredService<Supabase.Client>()));
// ...
}
public class AppStateService : INotifyPropertyChanged
{
// ...
public Supabase.Client Supabase;
private AuthState authState = AuthState.SignedOut;
public AuthState AuthState { get => authState; set => SetField(ref authState, value); }
private Session? session;
public Session? Session { get => session; set => SetField(ref session, value); }
private User? user;
public User? User { get => user; set => SetField(ref user, value); }
private async void Auth_StateChanged(object? sender, ClientStateChanged e)
{
AuthState = e.State;
Session = Supabase.Auth.CurrentSession;
User = Supabase.Auth.CurrentUser;
switch (e.State)
{
case AuthState.SignedIn:
await Shell.Current.GoToAsync("//accounts");
await Refresh();
break;
case AuthState.SignedOut:
Reset();
await Shell.Current.GoToAsync("//profile");
break;
}
}
// ...
} Using this setup, you can either reference builder.Services.AddTransient<AuthViewModel>(); public AppStateService AppState { get; private set; }
protected AuthViewModel(AppStateService appState)
{
AppState = appState;
} Or using the public AppStateService AppState { get; private set; }
protected BaseViewModel()
{
AppState = MauiProgram.GetService<AppStateService>()!;
} Supabase can be initialized once in public App(AppStateService appState, Supabase.Client supabase)
{
InitializeComponent();
MainPage = new AppShell();
}
protected override async void OnStart()
{
base.OnStart();
await Supabase.InitializeAsync();
} Does that help? |
Beta Was this translation helpful? Give feedback.
@RedChops I have been using the Dependency injection model with Maui by specifying
Supabase.Client
as a Singleton within the builder, and leverage it using anAppStateService
class like so:MauiProgram.cs