.NET MAUI Dependency Injection

Tuesday, June 14, 2022

Dependency Injection (DI) is a pattern that we use in continuation of separation of concerns. A class should only be interested in what it is doing, not newing up some other class. Just inject foreign classes into the constructor and be on your way. It’s that simple.

Why?

Our app is fairly small right now but as it gets bigger we’ll be thankful for dependency injection. If you look at the MainPage.xaml.cs file you see that we new up a MainViewModel right where we need it, but is it really the responsibility of MainPage.xaml.cs to create another class just to do its job? No. This create a tight coupling between the View and the ViewModel. That is a bad thing. So let’s inject the MainViewModel into this MainPage class.

How do we do that?

Dependency Injection is baked into .NET MAUI (and all of .NET for that matter). We don’t need extra libraries or NuGet packages. All we do is open the MauiProgram.cs file. In here we can see our app creates a builder that we then configure as a MAUI app and configure some default fonts. Then we build the builder and return it. Before we build the builder add two simple statements:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
using maui_to_do.ViewModels;

namespace maui_to_do;

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.AddSingleton<MainPage>();
		builder.Services.AddSingleton<MainViewModel>();

		return builder.Build();
	}
}

That’s all you have to do here. We are adding a couple singletons to the services, one for MainPage and one for MainViewModel. That means whenever a view (or whatever) requests a MainViewModel to be included in the constructor the same (singleton) MainViewModel will be supplied. And, as we’ll see soon, when we request a MainPage we’ll get the same main page back.

How do we use that?

In the App.xaml.cs file change the code to as follows:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
namespace maui_to_do;

public partial class App : Application
{
	public App(MainPage mp)
	{
		InitializeComponent();

		MainPage = mp;
	}
}

As you can see on line 5 we add a parameter to the constructor. A MainPage object is sent in and that is used on line 9 to initialize the MainPage parameter.

Now, on the MainPage.xaml.cs file. Change the constructor to include a parameter of MainViewModel and call it mvm. Then change the BindingContext to equal this mvm variable.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
using maui_to_do.ViewModels;

namespace maui_to_do;

public partial class MainPage : ContentPage
{
	public MainPage(MainViewModel mvm)
	{
		InitializeComponent();
		BindingContext = mvm;
	}
}

That’s it! We’ve just injected a dependency into our view! It’s easy isn’t it? You can run the app and it’ll look and function the same as last time because we’ve only inverted the control of creating that ViewModel and the MainPage.

The app running the same as before.

We’ll do more in the next blog post, but for now let me know what you think of this series so far.

.NET MAUIDependency InjectionInversion of ControlPatterns

This work is licensed under CC BY-NC-SA 4.0

.NET MAUI Services

.NET MAUI MVVM