Shell page dependency resolution optimization
See original GitHub issueDescription
Currently, the Shell page dependency resolution mechanism uses Extensions.DependencyInjection.ActivatorUtilities.GetServiceOrCreateInstance
. This allows Shell to create pages without having registered the pages with the service collection, and resolve any registered dependencies that the pages have in their constructor.
This is fairly inflexible, however; the page cannot have multiple constructors that have dependencies that can be satisfied. It may also cause problems when the page’s BindingContext
is set in XAML, and possibly other issues.
If this was changed to use IServiceProvider.GetService
, it would allow for multiple constructors. For example, if you had dependencies registered such as:
// ...
services.AddTransient<MainViewModel>();
// ...
This would allow for a page constructed by Shell to have multiple constructors, with arguments that aren’t resolved by the service provider, such as:
public TestPage(MainViewModel viewModel)
{
}
public TestPage(MainViewModel viewModel, OtherDependency arg2)
{
}
The first constructor will be selected by the resolution mechanism.
@PureWeen thoughts?
Public API Changes
The biggest impact is that for any code written using Preview 12, the pages to be constructed by Shell will, going forward, have to be registered with the service collection as part of the HostBuilder
. If the dev doesn’t do this, once this change was deployed, if they didn’t have a parameterless constructor defined, the MissingMethodException
would be thrown. This would therefore be a breaking change, but only since Preview 12.
This feature essentially then becomes “opt-in;” for any Shell pages defined with DataTemplate
or constructed via Routing navigation, if the pages are not registered, they must have a parameterless constructor, as they will be created by Activator.CreateInstance
. If they are registered, they will be resolved by IServiceProvider.GetService()
, and any of the registeed dependencies defined in their constructor will be resolved.
Intended Use-Case
This allows Shell to create pages without dependency resolution, and the pages can be constructed with dependency resolution if desired. It also allows multiple constructors to be defined, allowing more flexibility for the developer.
Issue Analytics
- State:
- Created 2 years ago
- Comments:13 (13 by maintainers)
@brunck so it looks like this is this is the reason why we’re all seeing a bit different results when testing this one out.
https://github.com/dotnet/maui/issues/4318#issuecomment-1023732279
So, until the issue referenced in that comment is fixed your approach might be the best.
Yeah, I’m relying on MAUI team to know what to do, thanks.