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 Property of Generic Type fails when creating an Assembly using Reflection.Emit and MetadataLoadContext. #112155

Open
AugustoRuiz opened this issue Feb 4, 2025 · 5 comments · May be fixed by #112372
Assignees
Labels
area-System.Reflection bug in-pr There is an active PR which will close this issue when it is merged
Milestone

Comments

@AugustoRuiz
Copy link

Describe the bug

Cannot create a property of a Generic Type whose Type parameter is created using Reflection.Emit, when creating an assembly using MetadataLoadContext to use Reference Assemblies.

I am creating a DLL using Reflection.Emit from a JSON based description. This DLL has entity types that have properties with basic types, or with types already defined in the assembly that is being created. That works, but if the property is of a generic type, such as a List, and the generic type parameter is a type defined in the assembly being created, a System.ArgumentException is raised when invoking Type.MakeGenericType([entityType]).

The error states:

This type 'Type: <entityType>' was not loaded by the MetadataLoadContext that loaded the generic type or method'.
   at System.Reflection.TypeLoading.RoDefinitionType.MakeGenericType(Type[] typeArguments)

To Reproduce

See the repository:

Repo in GitHub

Exceptions (if any)

System.ArgumentException:

An unhandled exception of type 'System.ArgumentException' occurred in System.Reflection.MetadataLoadContext.dll: 'This type 'Type: PurchaseOrderItem' was not loaded by the MetadataLoadContext that loaded the generic type or method.' at System.Reflection.TypeLoading.RoDefinitionType.MakeGenericType(Type[] typeArguments) at Program.<Main>$(String[] args) in ...\MetadataLoadContextError\Program.cs:line 37

Further technical details

  • Include the output of dotnet --info
SDK DE .NET:
 Version:           9.0.101
 Commit:            eedb237549
 Workload version:  9.0.100-manifests.3068a692
 MSBuild version:   17.12.12+1cce77968

Entorno de tiempo de ejecución:
 OS Name:     Windows
 OS Version:  10.0.19045
 OS Platform: Windows
 RID:         win-x64
 Base Path:   C:\Program Files\dotnet\sdk\9.0.101\

Cargas de trabajo de .NET instaladas:
No hay cargas de trabajo instaladas para mostrar.
Configurado para usar loose manifests al instalar nuevos manifiestos.

Host:
  Version:      9.0.0
  Architecture: x64
  Commit:       9d5a6a9aa4

.NET SDKs installed:
  8.0.300 [C:\Program Files\dotnet\sdk]
  9.0.101 [C:\Program Files\dotnet\sdk]

.NET runtimes installed:
  Microsoft.AspNetCore.App 8.0.5 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 9.0.0 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.NETCore.App 6.0.29 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 8.0.5 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 9.0.0 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.WindowsDesktop.App 6.0.29 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
  Microsoft.WindowsDesktop.App 8.0.5 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
  Microsoft.WindowsDesktop.App 9.0.0 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]

Other architectures found:
  x86   [C:\Program Files (x86)\dotnet]
    registered at [HKLM\SOFTWARE\dotnet\Setup\InstalledVersions\x86\InstallLocation]

Environment variables:
  Not set

global.json file:
  Not found

Learn more:
  https://aka.ms/dotnet/info

Download .NET:
  https://aka.ms/dotnet/download
  • The IDE (VS / VS Code/ VS4Mac) you're running on, and its version
Version: 1.96.4 (user setup)
Commit: cd4ee3b1c348a13bafd8f9ad8060705f6d4b9cba
Date: 2025-01-16T00:16:19.038Z
Electron: 32.2.6
ElectronBuildId: 10629634
Chromium: 128.0.6613.186
Node.js: 20.18.1
V8: 12.8.374.38-electron.0
OS: Windows_NT x64 10.0.19045
@dotnet-issue-labeler dotnet-issue-labeler bot added the untriaged New issue has not been triaged by the area owner label Feb 4, 2025
@marcpopMSFT marcpopMSFT transferred this issue from dotnet/sdk Feb 4, 2025
Copy link
Contributor

Tagging subscribers to this area: @dotnet/area-system-reflection
See info in area-owners.md if you want to be subscribed.

@jkotas
Copy link
Member

jkotas commented Feb 5, 2025

You should be able to workaround this by using Type.MakeGenericSignatureType to create generic Types from components that span multiple Type universes:

-var listOfPoiType = listContextType.MakeGenericType(poiType);
+var listOfPoiType = Type.MakeGenericSignatureType(listContextType, poiType);

For convenience, it may be nice if MakeGenericType implemented by System.Reflection.MetadataLoadContext does this as a fallback instead of throwing an exception.

@AugustoRuiz
Copy link
Author

This allows the creation of the Type, but then the PersistedAssemblyBuilder fails to save the Assembly.

It throws the following exception:

Exception has occurred: CLR/System.NotSupportedException An unhandled exception of type 'System.NotSupportedException' occurred in System.Private.CoreLib.dll: 'This method is not supported on signature types.' at System.Reflection.SignatureType.IsValueTypeImpl() at System.Reflection.Emit.MetadataSignatureHelper.WriteSignatureForType(SignatureTypeEncoder signature, Type type, ModuleBuilderImpl module) at System.Reflection.Emit.MetadataSignatureHelper.GetFieldSignature(Type fieldType, Type[] requiredCustomModifiers, Type[] optionalCustomModifiers, ModuleBuilderImpl module) at System.Reflection.Emit.ModuleBuilderImpl.WriteFields(TypeBuilderImpl typeBuilder, BlobBuilder fieldDataBuilder) at System.Reflection.Emit.ModuleBuilderImpl.AppendMetadata(MethodBodyStreamEncoder methodBodyEncoder, BlobBuilder fieldDataBuilder, MetadataBuilder& pdbBuilder) at System.Reflection.Emit.PersistedAssemblyBuilder.PopulateAssemblyMetadata(BlobBuilder& ilStream, BlobBuilder& fieldData, MetadataBuilder& pdbBuilder) at System.Reflection.Emit.PersistedAssemblyBuilder.SaveInternal(Stream stream) at System.Reflection.Emit.PersistedAssemblyBuilder.Save(String assemblyFileName) at Program.<Main>$(String[] args) in c:\Data\MetadataLoadContextError\Program.cs:line 44

I've updated the repository, using Fields instead of Properties, for brevity.

https://github.com/AugustoRuiz/MetadataLoadContextError

@jkotas
Copy link
Member

jkotas commented Feb 5, 2025

Hmmm, https://github.com/dotnet/runtime/blob/main/src/libraries/System.Private.CoreLib/src/System/Reflection/SignatureConstructedGenericType.cs is missing implementation for IsValueTypeImpl. It should just forward to the type definition like implementation of IsByRefLike.

@steveharter steveharter added this to the 10.0.0 milestone Feb 5, 2025
@steveharter steveharter added the bug label Feb 5, 2025
@steveharter steveharter self-assigned this Feb 5, 2025
@dotnet-policy-service dotnet-policy-service bot removed the untriaged New issue has not been triaged by the area owner label Feb 5, 2025
@dotnet-policy-service dotnet-policy-service bot added the in-pr There is an active PR which will close this issue when it is merged label Feb 10, 2025
@steveharter
Copy link
Member

@AugustoRuiz there is a PR up for v10 - do you need this ported to v9?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-System.Reflection bug in-pr There is an active PR which will close this issue when it is merged
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants