Back to results for “Best Practices & Architecture”
.NET MAUI › Best Practices & Architecture

How do you implement a navigation service to keep view models testable?

Intermediate

Answer

Wrap Shell navigation behind an INavigationService interface (GoToAsync-style methods) registered in DI, so view models depend on the abstraction rather than static Shell.Current. Tests supply a fake navigation service and assert navigations without a UI.
public interface INavigationService { Task GoToAsync(string route, IDictionary<string,object>? p = null); }
public class ShellNavigationService : INavigationService
{ public Task GoToAsync(string r, IDictionary<string,object>? p = null)
    => Shell.Current.GoToAsync(r, p ?? new Dictionary<string,object>()); }
Real-world example View models call _nav.GoToAsync so unit tests verify navigation happened without touching Shell.

Common follow-ups: Why abstract navigation? | How does this help testing?