Description
Description
When GetCustomAttributes<T>()
is called on a type defined in a dynamic assembly created with AssemblyBuilder which has a custom attribute referencing another type in the dynamic assembly, a System.IO.FileNotFoundException exception is thrown.
Also note that when adding a Resolve callback to the AppDomain or ApplicationLoadContext and returning the AssemblyBuilder that contains the dynamic assembly, an exception will be thrown: System.InvalidOperationException: Dynamically emitted assemblies are unsupported during host-based resolution.
, so this is not a possible workaround.
Reproduction Steps
using System.Reflection;
using System.Reflection.Emit;
namespace ReproDAGetCustomAttributes;
[AttributeUsage(AttributeTargets.Class)]
public class MyCustomAttribute(Type type) : Attribute
{
private readonly Type _type = type;
}
public static class Entry
{
public static void Main()
{
AssemblyName an = new("MyDnamicAssembly");
AssemblyBuilder ab = AssemblyBuilder.DefineDynamicAssembly(an, AssemblyBuilderAccess.RunAndCollect);
ModuleBuilder mb = ab.DefineDynamicModule(an.Name!);
TypeBuilder typeABuilder = mb.DefineType("TypeA", TypeAttributes.Class | TypeAttributes.Public);
Type typeA = typeABuilder.CreateType();
TypeBuilder typeBBuilder = mb.DefineType("TypeB", TypeAttributes.Class | TypeAttributes.Public);
CustomAttributeBuilder cab = new(typeof(MyCustomAttribute).GetConstructor([typeof(Type)])!, [typeA]);
typeBBuilder.SetCustomAttribute(cab);
Type typeB = typeBBuilder.CreateType();
typeB.GetCustomAttributes<MyCustomAttribute>(); // Throws exception
}
}
Expected behavior
typeB.GetCustomAttributes
should not throw an exception, and should return an instance of MyCustomAttribute
constructed with the type of TypeA from the dynamic assembly.
Actual behavior
An exception is thrown when attempting to get the custom attributes of TypeB:
System.IO.FileNotFoundException: Could not load file or assembly 'MyDnamicAssembly, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'. The system cannot find the file specified.
File name: 'MyDnamicAssembly, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'
at System.Reflection.RuntimeAssembly.InternalLoad(AssemblyName assemblyName, StackCrawlMark& stackMark, AssemblyLoadContext assemblyLoadContext, RuntimeAssembly requestingAssembly, Boolean throwOnFileNotFound)
at System.Reflection.TypeNameParser.ResolveAssembly(String assemblyName)
at System.Reflection.TypeNameParser.GetType(String typeName, ReadOnlySpan`1 nestedTypeNames, String assemblyNameIfAny)
at System.Reflection.TypeNameParser.Parse()
at System.Reflection.TypeNameParser.GetTypeHelper(Char* pTypeName, RuntimeAssembly requestingAssembly, Boolean throwOnError, Boolean requireAssemblyQualifiedName)
at System.Reflection.CustomAttribute._CreateCaObject(RuntimeModule pModule, RuntimeType type, IRuntimeMethodInfo pCtor, Byte** ppBlob, Byte* pEndBlob, Int32* pcNamedArgs)
at System.Reflection.CustomAttribute.AddCustomAttributes(ListBuilder`1& attributes, RuntimeModule decoratedModule, Int32 decoratedMetadataToken, RuntimeType attributeFilterType, Boolean mustBeInheritable, ListBuilder`1 derivedAttributes)
at System.Reflection.CustomAttribute.GetCustomAttributes(RuntimeType type, RuntimeType caType, Boolean inherit)
at System.Attribute.GetCustomAttributes(MemberInfo element, Type attributeType, Boolean inherit)
at System.Reflection.CustomAttributeExtensions.GetCustomAttributes[T](MemberInfo element)
at ReproDAGetCustomAttributes.Entry.Main()
Regression?
No response
Known Workarounds
No response
Configuration
Tested with .NET 8.0.0, & 8.0.1
Windows 10 (x64) & macOS 14.3.1 (23D60) (ARM64)
Other information
No response