Skip to content

Clean build produces empty GeneratedInternalTypeHelper.g.cs #7439

@glyph-se

Description

@glyph-se
  • .NET Core Version: 7.0.101 (using Visual Studio 17.4.3 for compilation)
  • Windows version: 11 22H2 (OS Build 22621.963)
  • Does the bug reproduce also in WPF for .NET Framework 4.8?: Yes
  • Is this bug related specifically to tooling in Visual Studio (e.g. XAML Designer, Code editing, etc...)? No

Problem description:
The problem occurs when having an internal constructor in a type referenced from XAML. In order for this to work, a GeneratedInternalTypehelper.g.cs should be automatically created as part of the build process. Without this file included in the resulting assembly there are runtime errors.

If a small change is made to the code, e.g. changing a comment and then doing a build without clean, it works as it should, producing the file. I have verified this both for net6 and netframework.

Actual behavior:
The generated GeneratedInternalTypeHelper.g.cs is empty. When launching the application the following crash / exception occurs:

System.Windows.Markup.XamlParseException
  HResult=0x80131501
  Message='No matching constructor found on type 'WpfApp1.UserControl1'. You can use the Arguments or FactoryMethod directives to construct this type.' Line number '11' and line position '2'.
  Source=PresentationFramework
  StackTrace:
   at System.Windows.Markup.XamlReader.RewrapException(Exception e, IXamlLineInfo lineInfo, Uri baseUri)
   at System.Windows.Markup.WpfXamlLoader.Load(XamlReader xamlReader, IXamlObjectWriterFactory writerFactory, Boolean skipJournaledProperties, Object rootObject, XamlObjectWriterSettings settings, Uri baseUri)
   at System.Windows.Markup.WpfXamlLoader.LoadBaml(XamlReader xamlReader, Boolean skipJournaledProperties, Object rootObject, XamlAccessLevel accessLevel, Uri baseUri)
   at System.Windows.Markup.XamlReader.LoadBaml(Stream stream, ParserContext parserContext, Object parent, Boolean closeStream)
   at System.Windows.Application.LoadComponent(Object component, Uri resourceLocator)
   at WpfApp1.MainWindow.InitializeComponent() in F:\git\poc-wpf-internal-types\WpfApp1\MainWindow.xaml:line 1

  This exception was originally thrown at this call stack:
    [External Code]

Inner Exception 1:
MissingMethodException: Constructor on type 'WpfApp1.UserControl1' not found.

Expected behavior:
There should always be a GeneratedInternalTypeHelper.g.cs generated with proper contents, regardless of how the project is built.

Minimal repro:
I created a new WPF app in Visual Studio, added a user control and changed the constructor of the user control to internal. Repo with this code is available here: https://github.com/glyph-se/poc-wpf-internal-types

Test steps:

  1. Rebuild
  2. Run
  3. Observe runtime exception
  4. Change a comment on the code
  5. Build
  6. Run
  7. Windows opens properly
  8. Change a comment on the code
  9. rebuild
  10. Run
  11. Observe runtime exception

Extra information:

This issue was encountered after conversion from old csproj format to the new SDK style, in the old format this works properly.

I have found some older open issues related to this, though they mostly talk about unnecessary rebuilds or non-deterministics builds. I'm not sure if they are the same or not. However, what I haven't found before is any mentioning of it actually breaking the output executable, which is the case here.

#2281
#2690

I have found a workaround which is to manually add the contents of the generated file to the project, and then exclude the generation of it, see: glyph-se/poc-wpf-internal-types@main...workaround

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions