Source generators cause compiler errors in XAML compilation (MarkupCompilePass1)
- Dominant language
- C#
- Stars
- 7.7k
- Forks
- 1.3k
- Avg merge
- 1d 11h
- Merged PRs (30d)
- 61
Description
### Description
When using source generators (in this case the ones from `MessagePack` wich generate internal-only code) in combination with `compile`, compilation of XAML fails in `MarkupCompilePass1` because the now private assembly can not be found be the XAML compiler, even though that assembly is not used in any public API.
The repo https://github.com/bitbonk/Rerpoduce-MessagePackNotFound demonstrates this. A compiler error occurs when you reference a project that uses MessagePack with source generators in a WPF user control library that contains XAML.
If you build the project you will see the the following compiler error in the WPF project
`MessagePackNotFound.UserControlsLib` generated by `Microsoft.Build.Tasks.Windows.MarkupCompilePass1` from `PresentationBuildTasks.dll`:
> Microsoft.WinFX.targets(211,9): Error MC1000 : Unknown build error, 'Could not find assembly 'MessagePack,
> Version=3.1.4.0, Culture=neutral, PublicKeyToken=b4a0369545f0a1be'. Either explicitly load this assembly using a
> method such as LoadFromAssemblyPath() or use a MetadataAssemblyResolver that returns a valid assembly.'
These conditions must be met for the error to occur:
1. A project (`CommonLib`) references and uses MessagePack.
2. MessagePack generates source code in `CommonLib` using its source generators.
3. `CommonLib` references the MessagePack nuget package with
`Analyzers; Build; ContentFiles; Compile`
_!! The goal behind this `` is to hide the MessagePack public APIs from anynone using the
`CommonLib` nuget package.
That `CommonLib` uses MessagePack under the hood is purely an implementation detail and
MessagePack should not become part of the public API of `CommonLib`. !!_
4. `CommonLib` is referenced by a WPF project (`UserControlsLib`) that contains XAML that needs to be compiled.
This has to do something with the code that is generated by the MessagePack source generators. As soon as MessagePack generates code (that is all internal) inside of `CommonLib`, `Microsoft.Build.Tasks.Windows.MarkupCompilePass1` wants to load `MessagePack.dll` wen compiling the XAML. Even though there are no types of MessagePack in the public API of `CommonLib`.
- If you downgrade MessagePack from `3.1.4` to `2.5.198`, the problem will go away because the older version of MessagePack did not have source generators.
- If you remove the attribute `[MessagePackObject(AllowPrivate = true)]` from the `Dto` class in `CommonLib`, the
problem will go away, because then no source code is generated by the source generators of MessagePack.
- If you remove the private assets element (`Analyzers; Build; ContentFiles; Compile`) from the MessagePack package reference in `MessagePackNotFound.CommonLib.csproj`, the problem will go away, because `MessagePack.dll` can now be found.
For testing, this repo also contains an `App` that references `UserControlsLib` as a nuget package. However the solution looks like, `App` must compile without errors and ideally does not "see" any MessagePack APIs.
### Reproduction Steps
Clone the repo and build the solution.
### Expected behavior
The solution builds without errors.
### Actual behavior
The following compiler error occurs in the WPF XAML project.
> Microsoft.WinFX.targets(211,9): Error MC1000 : Unknown build error, 'Could not find assembly 'MessagePack,
> Version=3.1.4.0, Culture=neutral, PublicKeyToken=b4a0369545f0a1be'. Either explicitly load this assembly using a
> method such as LoadFromAssemblyPath() or use a MetadataAssemblyResolver that returns a valid assembly.'
### Regression?
don't know
### Known Workarounds
See above,.
The only somewhat feasible workaround would be to remove the private assets entry. But that will make the API public to all users of `CommonLib`.
### Impact
_No response_
### Configuration
_No response_
### Other information
_No response_
Contributor guide
Assessment
This issue has not been assessed yet.