.NET MAUI – Forget Me Not – Part 6

Building on the previous postings, today I want to discuss the magic of Dependency Injection (DI)

Dependency Injection makes for cleaner and more testable code. We’ll get into testing and Mocks in a later blog post, but using DI allows you to substitute a mock service for a real one. In any case, it is magical.

Even though this is powerful, this posting will be short, because once you know how to do it, it is very easy.

Let’s look at BuddyPreferences. This is the page that lists all the preferences of a specific buddy. We start, in BuddyPreferences.xaml.cs by creating BuddyPreferencesViewModel so that it can be our BindingContext. We pass the ViewModel into the constructor. Here is the complete class:

public partial class BuddyPreferences : ContentPage
{
    private BuddyPreferencesViewModel vm;
    public BuddyPreferences(BuddyPreferencesViewModel vm)
    {
       this.vm = vm;
       BindingContext = vm;
       InitializeComponent();
    }

}

As you can see, the BuddyPreferenceViewModel is passed in. But where does it come from? Who passes it in? That is the magic of an InversionOfControl (IOC) container, which .NET MAUI provides to you for free. All you need do is register all your pages, viewmodels and services in MauiProgram.cs:

var builder = MauiApp.CreateBuilder();
builder
    .UseTelerik()
	.UseMauiApp<App>()
    .UseMauiCommunityToolkit()
    .ConfigureFonts(fonts =>
	{
		fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
		fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
	});


// Pages
 builder.Services.AddTransient<About>();
 builder.Services.AddTransient<BuddyDetail>();
 builder.Services.AddTransient<BuddyList>();
 builder.Services.AddTransient<View.Preferences>();

// Services
builder.Services.AddSingleton<BuddyService>();
builder.Services.AddTransient <PreferencesService>();

// ViewModel
builder.Services.AddTransient<BuddyListViewModel>();
builder.Services.AddTransient<BuddyDetailViewModel>();
builder.Services.AddTransient<BuddyPreferencesViewModel>();

return builder.Build();

As you can see in this excerpt of Mauiprogram.cs, we’ve registered the BuddyPreferences page, and the viewModel (Note, the reason we write View.Preferences is to avoid a name collision).

With that in place, the BuddyPreferencesViewModel is supplied by .NET MAUI to the constructor of BuddyPreferences, as shown above. You do not ever new-up a BuddyPreferencesViewModel – the creation of the VM is taken care of for you.

Notice that BuddyPreferencesViewModel is marked with AddTransient. There are two ways to add a page/service/view to the IoC – Transient and Singleton. If you make something a singleton as we do with the BuddyService then each time you get the service you get the same one. If you mark it transient, then each time you get it, you get a new one. General guidence is to use Singleton if you’ll be getting that object a lot (save memory) or if you need to preserve state.

The ViewModel itself depends on having an instance of BuddyService. We give it to BuddyPreferencesViewModel in the same way, by injecting it into the constructor

 private readonly BuddyService buddyService;

 public BuddyPreferencesViewModel(BuddyService buddyService)
 {
     ShowActivityIndicator = true;
     this.buddyService = buddyService;
 }

Go back and look at the creation of the BuddyPreferencesViewModel. No where is a new BuddyService “newed-up” and passed in. The Buddy Service is there because you registered it and so MAUI knows where to find it and what it depnds on. MAUI will not only create the BuddyService, but also any other classes in the chain of dependencies.

You’ll see this pattern throughout ForgetMeNot, and any well designed MaUI program.

Note: This pattern and Inversion of Control containers have been around for a long time. What is very nice here is that it is all built into MAUI.

About Jesse Liberty

Jesse Liberty has three decades of experience writing and delivering software projects and is the author of 2 dozen books and a couple dozen online courses. His latest book, Building APIs with .NET will be released early in 2025. Liberty is a Senior SW Engineer for CNH and he was a Senior Technical Evangelist for Microsoft, a Distinguished Software Engineer for AT&T, a VP for Information Services for Citibank and a Software Architect for PBS. He is a Microsoft MVP.
This entry was posted in Essentials and tagged , , . Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.