Summary: I am hoping to use MAUI's builder.Services
to resolve services in ViewModels, but I don't understand how to do so.
I could create my own IServiceProvider
, but I am hoping to avoid the needed boilerplate code, so instead I seek a "standard MAUI" solution.
I added the following line to MauiProgram.CreateMauiApp()
:
builder.Services.AddSingleton<IAlertService, AlertService>();
And the corresponding declarations (in other files):
public interface IAlertService
{
// ----- async calls (use with "await") -----
Task ShowAlertAsync(string title, string message, string cancel = "OK");
Task<bool> ShowConfirmationAsync(string title, string message, string accept = "Yes", string cancel = "No");
}
internal class AlertService : IAlertService
{
// ----- async calls (use with "await") -----
public Task ShowAlertAsync(string title, string message, string cancel = "OK")
{
return Application.Current.MainPage.DisplayAlert(title, message, cancel);
}
public Task<bool> ShowConfirmationAsync(string title, string message, string accept = "Yes", string cancel = "No")
{
return Application.Current.MainPage.DisplayAlert(title, message, accept, cancel);
}
}
Then in my BaseViewModel class:
internal class BaseViewModel
{
protected static IAlertService AlertSvc = ??? GetService (aka Resolve) ???
public static void Test1()
{
Task.Run(async () =>
await AlertSvc.ShowAlertAsync("Some Title", "Some Message"));
}
}
Question: How fill AlertSvc
with the service registered in MauiProgram?
CREDIT: Based on a suggested "DialogService" in some SO discussion or MAUI issue. Sorry, I've lost track of the original.
All the dependencies will be provided through the IServiceProvider
implementation that is part of .NET MAUI. Luckily, the IServiceProvider
itself is added to the dependency injection container as well, so you can do the following.
Add what you need to your dependency injection container in the MauiProgram.cs
:
builder.Services.AddSingleton<IStringService, StringService>();
builder.Services.AddTransient<FooPage>();
For completeness, my StringService
looks like this:
public interface IStringService
{
string GetString();
}
public class StringService : IStringService
{
public string GetString()
{
return "string";
}
}
Then in your FooPage
, which can also be your view model or anything of course, add a constructor like this:
public FooPage(IServiceProvider provider)
{
InitializeComponent();
var str = provider.GetService<IStringService>().GetString();
}
Here you can see that you resolve the service manually through the IServiceProvider
and you can call upon that. Note that you'll want to add some error handling here to see if the service actually can be resolved.