Dependency Injection in .NET MAUI MVVM

Tip: Dependency Injection (DI) is a fundamental design pattern that promotes loosely coupled and maintainable code. It's crucial for building robust applications with .NET MAUI, especially within the MVVM architecture.

What is Dependency Injection?

Dependency Injection is a design pattern where a class receives its dependencies from an external source rather than creating them itself. Instead of a class instantiating its own dependencies, they are "injected" into the class, typically through its constructor, a property, or a method. This makes classes more modular, testable, and easier to manage.

Why Use DI in .NET MAUI?

Integrating DI with .NET MAUI

.NET MAUI has built-in support for a lightweight dependency injection container. You configure and register your services in your application's startup code (e.g., MauiProgram.cs).

Configuring the DI Container

The entry point for your .NET MAUI application is typically the MauiProgram.cs file. Here, you can configure the services that will be available for injection.

MauiProgram.cs Example


using Microsoft.Extensions.DependencyInjection;
using YourAppName.Services;
using YourAppName.ViewModels;
using YourAppName.Views;

public static class MauiProgram
{
    public static MauiApp CreateMauiApp()
    {
        var builder = MauiApp.CreateBuilder();
        builder
            .UseMauiApp()
            .ConfigureFonts(fonts =>
            {
                fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
                fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
            });

        // Register services
        builder.Services.AddSingleton();
        builder.Services.AddTransient();

        // Register ViewModels
        builder.Services.AddTransient();
        builder.Services.AddTransient();

        // Register Pages if needed (often done implicitly through navigation)
        // builder.Services.AddTransient();
        // builder.Services.AddTransient();

        return builder.Build();
    }
}
            

Registering Services

You can register services with different lifetimes:

Injecting Dependencies into ViewModels

Once services are registered, you can inject them into your ViewModels via the constructor.

SampleViewModel.cs Example


using YourAppName.Services;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;

public partial class HomePageViewModel : ObservableObject
{
    private readonly IMessageService _messageService;
    private readonly ISampleService _sampleService;

    [ObservableProperty]
    private string _message;

    public HomePageViewModel(IMessageService messageService, ISampleService sampleService)
    {
        _messageService = messageService;
        _sampleService = sampleService;

        LoadMessageCommand.Execute(null); // Load initial message
    }

    [RelayCommand]
    private async Task LoadMessage()
    {
        Message = await _messageService.GetWelcomeMessageAsync();
        // You can also use _sampleService here for other operations
        var data = _sampleService.GetData();
        System.Diagnostics.Debug.WriteLine($"Sample service data: {data}");
    }
}
            

Resolving Dependencies for Pages/Views

When using MVVM, your pages typically instantiate ViewModels. The .NET MAUI DI container can resolve these ViewModels, and because the ViewModels depend on services, those services will also be resolved and injected automatically.

HomePage.xaml.cs Example


using YourAppName.ViewModels;

public partial class HomePage : ContentPage
{
    // The HomePageViewModel is resolved and injected by the DI container
    public HomePage(HomePageViewModel viewModel)
    {
        InitializeComponent();
        BindingContext = viewModel;
    }
}
            

Important: When you use AddTransient for a ViewModel, a new instance is created each time the page is navigated to. For singletons or objects that should persist across navigation, use AddSingleton or consider a different approach for managing ViewModel instances.

Advanced DI Concepts

Conclusion

Leveraging Dependency Injection in your .NET MAUI MVVM applications is a powerful way to write clean, testable, and maintainable code. By configuring the DI container in MauiProgram.cs and injecting services into your ViewModels and Pages, you can build more robust and scalable cross-platform applications.