I already tried this but it didn't work for me. GetService
returns null
.
Disclaimer: This is a MRE (minimal reproducable example), so please don't suggest a way that doesn't use the service.
I have a ContentView from which I want to access my singletons that have been added to the dependency injector.
I want LuckyNumberText
to contain a random number using the service. However, because it's a content view, the constructor has to be parameterless and thus cannot be injected.
App.xaml
<?xml version = "1.0" encoding = "UTF-8" ?>
<Application xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:MauiMRE"
x:Class="MauiMRE.App">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Resources/Styles/Colors.xaml" />
<ResourceDictionary Source="Resources/Styles/Styles.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
App.xaml.cs
namespace MauiMRE;
public partial class App : Application
{
public static IServiceProvider Services => ServiceProvider.Current;
public App()
{
InitializeComponent();
MainPage = new AppShell();
}
}
AppShell.xaml
<?xml version="1.0" encoding="UTF-8" ?>
<Shell
x:Class="MauiMRE.AppShell"
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:MauiMRE"
Shell.FlyoutBehavior="Disabled">
<ShellContent
Title="Home"
ContentTemplate="{DataTemplate local:MainPage}"
Route="MainPage" />
</Shell>
AppShell.xaml.cs
namespace MauiMRE;
public partial class AppShell : Shell
{
public AppShell()
{
InitializeComponent();
}
}
Mainpage.xaml
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MauiMRE.MainPage"
xmlns:local="clr-namespace:MauiMRE"
>
<local:MyContentView></local:MyContentView>
</ContentPage>
MainPage.xaml.cs
namespace MauiMRE;
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
}
}
MauiProgram.cs
using Microsoft.Extensions.Logging;
namespace MauiMRE;
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");
});
#if DEBUG
builder.Logging.AddDebug();
#endif
builder.Services.AddSingleton<MyContentView>();
builder.Services.AddSingleton<MyContentViewModel>();
builder.Services.AddSingleton<MyService>();
return builder.Build();
}
}
MyContentView.xaml
<?xml version="1.0" encoding="utf-8" ?>
<ContentView xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MauiMRE.MyContentView">
<VerticalStackLayout>
<Label
Text="{Binding LuckyNumberText}"
VerticalOptions="Center"
HorizontalOptions="Center" />
</VerticalStackLayout>
</ContentView>
MyContentView.xaml.cs
namespace MauiMRE;
public partial class MyContentView : ContentView
{
public MyContentView()
{
InitializeComponent();
BindingContext = new MyContentViewModel();
}
}
MyContentViewModel.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MauiMRE;
public class MyContentViewModel
{
public MyContentViewModel()
{
var service = ServiceProvider.GetService<MyService>();
var result = service.RandomInt(); // crashes before this line is reached
}
public string LuckyNumberText
{
get
{
return $"Lucky number: {1}";
}
}
}
MyService.cs
namespace MauiMRE
{
public static class ServiceProvider
{
public static T GetService<T>()
{
var current = Current; // runs
return current.GetService<T>(); // crashes
}
public static IServiceProvider Current
=>
#if WINDOWS10_0_17763_0_OR_GREATER
MauiWinUIApplication.Current.Services;
#elif ANDROID
MauiApplication.Current.Services; // pretty sure this line crashes
#else
null;
#endif
}
}