Skip to content
This repository was archived by the owner on Nov 8, 2025. It is now read-only.

2 Using the dependency registration source generator

Matt Goldman edited this page Oct 16, 2023 · 9 revisions

2.1 Introduction

With the latest version of Maui.Plugins.PageResolver, you can automatically register all of your dependencies (Pages, ViewModels, Services and associated interfaces).

Autoreg is conventions based, so make sure you follow the conventions for it to work as expected.

This feature uses a source generator to scan your project and automatically register these dependencies for you. Because it is a source generator, the code is included at compile-time, which has no runtime impact (compared to, say, something using reflection).

Follow the instructions below to simplify dependency registration, use PageResolver, and remove a whole load of common boilerplate code from your .NET MAUI projects.

Once you have completed these steps, use the PageResolver as per the instructions in step 1.4 of the using PageResolver instructions.

2.2 Requirements

Autoreg only works for single-project .NET MAUI apps. If you have created additional class libraries for your Pages, ViewModels or Services, use the PageResolver package and register these dependencies in code.

Setup

Install the required packages:

dotnet add package Goldie.MauiPlugins.PageResolver
dotnet add package Goldie.MauiPlugins.PageResolver.Auoreg

Change your MauiProgram class declaration to partial, and add a partial method declaration for Autoreg:

namespace MyApp
{
    // ADD partial TO THE CLASS DEFINITION
    public static partial class MauiProgram
    {
        public static MauiApp CreateMauiApp()
        {
            var builder = MauiApp.CreateBuilder();
            builder
            .UseMauiApp<App>()				
            .ConfigureFonts(fonts =>
            {
                fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
            });

            // YOU DON'T NEED THESE ANYMORE
            // builder.Services.AddSingleton<IMyService, MyService>();
            // builder.Services.AddTransient<MyViewModel>();
            // builder.Services.AddTransient<MyPage>();
            // builder.Services.UsePageResolver();

            // USE THIS INSTEAD
            UseAutoreg(builder.Services);

            return builder.Build();
        }
        
        // ADD THIS PARTIAL METHOD DECLARATION
        static partial void UseAutoreg(IServiceCollection services);
    }
}

That's it! If you've followed these steps, and the conventions below, all of your Pages, ViewModels and Services (and their associated interfaces) will be automatically registered on build, and you can use await Navigation.PushAsync<MyPage>(); without any further effort.

2.3 Conventions

Maui.Plugins.PageResolver.Autoreg will automatically register Pages, ViewModels and Services for you based on the following conventions.

You can still use PageResolver (and Autoreg) without following the conventions, but anything you want to register in the DI container that does not follow these conventions, you will need to register yourself.

2.3.1 Pages

Any class with a class name that ends with Page will be automatically registered with the DI container.

All pages are registered with TRANSIENT scope.

Examples:

Files Class name
MainPage.xaml, MainPage.xaml.cs MainPage <-- This will be registered
ProductPage.cs ProductPage <-- This will be registered
ProductView.xaml, ProductView.xaml.cs ProductView <-- This will NOT be automatically registered

2.3.2 ViewModels

Any class with a class name that ends with ViewModel will be automatically registered with the DI container.

All ViewModels are registered with TRANSIENT scope.

Examples:

Files Class name
MainPageViewModel.cs MainPageViewModel <-- This will be registered
ProductViewModel.cs ProductViewModel <-- This will be registered
ProductModel.cs ProductModel <-- This will NOT be automatically registered

2.3.4 Services

Any class with a class name that ends with Service will be automatically registered with the DI container.

All Services are registered with Singleton scope.

For interfaces with a name that matches the pattern I[...]Service, services are registered as an implementation of they interface they match.

Example #1:

Let's say you define an interface called IMappingService, and create a class that implements it called MappingService. These will be automatically registered for you:

services.AddSingleton<IMappingService, MappingService>();

Example #2:

Let's say you have a class in your project called NetworkService, but it does not implement any interface, this will be automatically registered for you:

services.AddSingleton<NetworkService>();

This can still be injected into the constructor of your Pages or ViewModels:

public MyViewModel(NetworkService networkService)
{
   ...

Example #3:

Let's say you have an interface called IPaymentService, and you have two classes that implement it: StripeService and MockPaymentService. Both of these will be registered automatically, but neither will be registered as an implementation of the interface:

services.AddSingleton<StripeService>();
services.AddSingleton<MockPaymentService>();

You will need to register these implementations yourself in code.

Clone this wiki locally