Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Creating a Page using a DataTemplate does not support Dependency Injection #3698

Closed
IndianaGary opened this issue Dec 8, 2021 · 2 comments
Closed
Labels
platform/windows 🪟 t/bug Something isn't working
Projects

Comments

@IndianaGary
Copy link

Description

On Maui: executing the application created below results in a MissingMethodException as shown in Log output.

I am implementing a Shell-based application with several ShellContent elements in AppShell.cs:

<ShellContent Title="About" ContentTemplate="{DataTemplate views:AboutPage}" />

The AboutPage, like all my other pages, is based on a custom class I wrote, ContentPageBase, that inherits ContentPage and supports injection of the view model via constructor injection.

public partial class AboutPage : ContentPageBase
{
public AboutPage( AboutViewModel vm ) : base( vm ) => InitializeComponent();
}

The page and view model are registered in MauiProgram.cs as follows; it is not otherwise created:

// Register About page
builder.Services.AddSingleton<AboutViewModel>();
builder.Services.AddTransient<AboutPage>();

Although registration differs between Xamarin Forms with Autofac and Maui with Microsoft dependency injection, the code works properly in Xamarin Forms, although the code paths between the two could be very different.

Steps to Reproduce

  1. Create a Shell-based application
  2. Create an application Page that takes a constructor parameter (in my case, the view model)
  3. Reference the Page in AppShell.cs
    example: <ShellContent Title="About" ContentTemplate="{DataTemplate views:AboutPage}" />
  4. Run the application
  5. Application crashes with a MissingMethodException.

Version with bug

Preview 10 (current)

Last version that worked well

Unknown/Other

Affected platforms

Windows, I was not able test on other platforms

Affected platform versions

Windows 10.0.18362.0 and up

Did you find any workaround?

No workaround, however working with redth, he located relevant code in maui/src/Controls/src/Core/ElementTemplate.cs.

LoadTemplate = () => Activator.CreateInstance(type);

The ElementTemplate constructor calls Activator.CreateInstance(type) without consulting the DI container whether or not dependency injection should occur. He suggested a possible correction could do something like the following:

LoadTemplate = () => Services.GetService(type) ?? Activator.CreateInstance(type);

Which suggests a possible fix.

Relevant log output

System.MissingMethodException
  HResult=0x80131513
  Message=Cannot dynamically create an instance of type 'LogViewer.Views.AboutPage'. Reason: No parameterless constructor defined.
  Source=System.Private.CoreLib
  StackTrace:
   at System.RuntimeType.ActivatorCache..ctor(RuntimeType rt)
   at System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean wrapExceptions)
   at System.Activator.CreateInstance(Type type, Boolean nonPublic, Boolean wrapExceptions)
   at System.Activator.CreateInstance(Type type)
   at Microsoft.Maui.Controls.ElementTemplate.<>c__DisplayClass4_0.<.ctor>b__0()
   at Microsoft.Maui.Controls.ElementTemplate.CreateContent()
   at Microsoft.Maui.Controls.Internals.DataTemplateExtensions.CreateContent(DataTemplate self, Object item, BindableObject container)
   at Microsoft.Maui.Controls.ShellContent.Microsoft.Maui.Controls.IShellContentController.GetOrCreateContent()
   at Microsoft.Maui.Controls.Platform.ShellSectionView.NavigateToShellSection(ShellSection section)
   at Microsoft.Maui.Controls.Platform.ShellItemView.OnShellSectionChanged(ShellSection oldSection, ShellSection newSection)
   at Microsoft.Maui.Controls.Platform.ShellItemView.set_ShellSection(ShellSection value)
   at Microsoft.Maui.Controls.Platform.ShellItemView.NavigateToShellItem(ShellItem newItem, Boolean animate)
   at Microsoft.Maui.Controls.Platform.ShellView.SwitchShellItem(ShellItem newItem, Boolean animate)
   at Microsoft.Maui.Controls.Platform.ShellView.OnElementSet(Shell shell)
   at Microsoft.Maui.Controls.Platform.ShellView.SetElement(VisualElement element)
   at Microsoft.Maui.Controls.Handlers.ShellHandler.SetVirtualView(IView view)
   at Microsoft.Maui.Handlers.ViewHandler`2.SetVirtualView(IElement view)
   at Microsoft.Maui.Controls.Element.SetHandler(IElementHandler newHandler)
   at Microsoft.Maui.Controls.Element.set_Handler(IElementHandler value)
   at Microsoft.Maui.HandlerExtensions.ToNative(IElement view, IMauiContext context)
   at Microsoft.Maui.Controls.Window.MapContent(WindowHandler handler, IWindow view)
   at Microsoft.Maui.PropertyMapper.UpdatePropertyCore(String key, IElementHandler viewHandler, IElement virtualView)
   at Microsoft.Maui.PropertyMapper.UpdateProperties(IElementHandler viewHandler, IElement virtualView)
   at Microsoft.Maui.Handlers.ElementHandler.SetVirtualView(IElement view)
   at Microsoft.Maui.Controls.Element.SetHandler(IElementHandler newHandler)
   at Microsoft.Maui.Controls.Element.set_Handler(IElementHandler value)
   at Microsoft.Maui.HandlerExtensions.SetHandler(IWinRTObject nativeElement, IElement element, IMauiContext context)
   at Microsoft.Maui.HandlerExtensions.SetWindowHandler(Window nativeWindow, IWindow window, IMauiContext context)
   at Microsoft.Maui.Platform.ApplicationExtensions.CreateNativeWindow(Application nativeApplication, IApplication application, LaunchActivatedEventArgs args)
   at Microsoft.Maui.MauiWinUIApplication.OnLaunched(LaunchActivatedEventArgs args)
   at LogViewer.WinUI.App.OnLaunched(LaunchActivatedEventArgs args) in D:\Projects\Maui\LogViewer\Platforms\Windows\App.xaml.cs:line 23
   at Microsoft.UI.Xaml.Application.Microsoft.UI.Xaml.IApplicationOverrides.OnLaunched(LaunchActivatedEventArgs args)
   at ABI.Microsoft.UI.Xaml.IApplicationOverrides.Do_Abi_OnLaunched_0(IntPtr thisPtr, IntPtr args)
@IndianaGary IndianaGary added the t/bug Something isn't working label Dec 8, 2021
@jsuarezruiz jsuarezruiz added this to New in Triage via automation Dec 9, 2021
@brunck
Copy link
Contributor

brunck commented Dec 9, 2021

Appears to duplicate #3147 . See #3375 for implementation (in progress).

@PureWeen
Copy link
Member

PureWeen commented Jan 5, 2022

#3375

@PureWeen PureWeen closed this as completed Jan 5, 2022
Triage automation moved this from New to Done Jan 5, 2022
@ghost ghost locked as resolved and limited conversation to collaborators Feb 18, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
platform/windows 🪟 t/bug Something isn't working
Projects
No open projects
Development

No branches or pull requests

4 participants