Skip to content

Proposal:Is it possible to support dependency injection when navigating between pages? #10892

@polarove

Description

@polarove

Title

Add alternative ways to resolve pages except types, such as factory methods or dependency injection.

Summary

Now
Frame.Navigate(Type pageType, Arg args, TransitionInfo transition);

Expecting methods
Frame.Navigate<HomePage>(args, transition);
Where HomePage can be resolved from the DI container, such as Microsoft.Extensions.DependencyInjection, with its dependencies resolved as well.

or factory method
Frame.Navigate<HomePage>(() => new HomePage(), args, transition);

Rationale

  1. Dependency can't be resolved when navigation lands, since the Frame.Navigate(...) method has its own way to create the instance of pages by given type.
//                               👇 The type HomePageViewModel can't be resolved from the DI container.
public partial class HomePage(HomePageViewModel vm) : Page 
{
}
  1. As the application developed, switching tags with page type is not intuitive.
args.InvokedItemContainer.Tag switch {
     nameof(...) => typeof(...)
     // the rest of code is all nameof(...) => typeof(...)
}
  1. So I created an ImmutableDictionary<string, Type> which includes all the pages that can be navigated to, but it needs manual management still.
public readonly static ImmutableDictionary<Route, Type> Routes = new Dictionary<Route, Type>
{
    { Route.HomePage, typeof(HomePage) },
    { Route.FissureSubscribeRulePage, typeof(FissureSubscribeRulePage) },
    { Route.SubscribedFissurePage, typeof(SubscribedFissurePage) },
    { Route.SimpleFissurePage, typeof(SimpleFissurePage) },
    { Route.HardFissurePage, typeof(HardFissurePage) },
    { Route.VoidStormFissurePage, typeof(VoidStormFissurePage) },
    { Route.SettingsPage, typeof(SettingsPage) }
}.ToImmutableDictionary();
  1. What if we
// register services
var builder = Host.CreateApplicationBuilder();
builder.services.AddTransient<HomePageViewModel>();
builder.services.AddTransient<HomePage>();
builder.Build();

// HomePage.xaml.cs
public partial class HomePage : Page 
{
    public HomePage(HomePageViewModel vm) 
    {
          DataContext = vm;
    }
}

Scope

Capability Priority
This proposal will allow developers to accomplish W Must
This proposal will allow end users to accomplish X Should
This proposal will allow developers to accomplish Y Could
This proposal will allow end users to accomplish Z Won't

Important Notes

No response

Open Questions

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    Status

    Backlog

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions