Type resolution depends on the program that is running, not the assembly being processed.
See original GitHub issueAn assembly built to target the .Net Framework expects to resolve system references in the GAC; however a .net (core) program using Cecil to manipulate that assembly resolves them to the trusted locations under dotnet/shared. The two files will not always match up.
Here’s an example – ClassLibrary.csproj
builds a WPF-consuming assembly that references WindowsBase.dll
v4.0.0.0 in the GAC. CecilGAC.csproj
is a simple .net6.0 program that reads and rewrites the ClassLibrary1.dll
assembly.
The program fails during write with
Mono.Cecil.ResolutionException: Failed to resolve System.Windows.Threading.DispatcherPriority
at Mono.Cecil.Mixin.CheckedResolve(TypeReference self)
...
because a WindowsBase.dll
v4.0.0.0 has been found within C:\Program Files\dotnet\shared\Microsoft.NETCore.App
; but that assembly is a stub containing only
internal class <Module>
{
}
However, if CecilGAC.csproj
is modified to be
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net48</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies.net48" Version="1.0.2">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Mono.Cecil" Version="0.11.4" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\ClassLibrary1\ClassLibrary1.csproj" />
</ItemGroup>
</Project>
building against .Net Framework v4.8, the write operation finds the expected file in the GAC, and the type resolution completes successfully.
Because a suitable strong-named assembly has been found in the ,net core case, a simple reactive approach such as overriding the AssemblyResolver to handle resolution failures by checking the GAC (if present) does not resolve the issue; the necessary fix would be to replace the #if NET_CORE
compile-time logic with a runtime selection based on the [TargetFramework]
attribute value of the assembly being manipulated.
[ADDED] An alternative would be to recognise such a pure stub assembly and consider it an assembly resolution failure; this form of stub seems to be a standard pattern for GUI-related assemblies.
Issue Analytics
- State:
- Created a year ago
- Reactions:1
- Comments:7 (7 by maintainers)
You can get the attribute type name and examine the associated binary blob data w/o any resolver as the following example demonstrates
Is there no chicken/egg issue with trying to have the behaviour of the resolver depend on
[TargetFramework]
? For one thing, I would expect it would need to resolveTargetFrameworkAttribute
before being able to look at the target framework value.