diff --git a/src/mono/mono/metadata/sre.c b/src/mono/mono/metadata/sre.c index de94e8c4bf9a3..3f47f9e84d008 100644 --- a/src/mono/mono/metadata/sre.c +++ b/src/mono/mono/metadata/sre.c @@ -1289,6 +1289,7 @@ image_module_basic_init (MonoReflectionModuleBuilderHandle moduleb, MonoError *e * determined at assembly save time. */ /*image = (MonoDynamicImage*)ab->dynamic_assembly->assembly.image; */ + MonoAssemblyLoadContext *alc = mono_alc_get_default (); MonoStringHandle abname = MONO_HANDLE_NEW_GET (MonoString, ab, name); char *name = mono_string_handle_to_utf8 (abname, error); return_val_if_nok (error, FALSE); @@ -1300,6 +1301,7 @@ image_module_basic_init (MonoReflectionModuleBuilderHandle moduleb, MonoError *e } MonoDynamicAssembly *dynamic_assembly = MONO_HANDLE_GETVAL (ab, dynamic_assembly); image = mono_dynamic_image_create (dynamic_assembly, name, fqname); + image->image.alc = alc; MONO_HANDLE_SETVAL (MONO_HANDLE_CAST (MonoReflectionModule, moduleb), image, MonoImage*, &image->image); MONO_HANDLE_SETVAL (moduleb, dynamic_image, MonoDynamicImage*, image); diff --git a/src/tests/Loader/CustomAttributes/DynamicObjects.cs b/src/tests/Loader/CustomAttributes/DynamicObjects.cs new file mode 100644 index 0000000000000..5b232d83eba3b --- /dev/null +++ b/src/tests/Loader/CustomAttributes/DynamicObjects.cs @@ -0,0 +1,107 @@ +using System; +using System.Resources; +using System.Reflection; +using System.Reflection.Emit; +using System.ComponentModel.DataAnnotations; +using System.Linq; + +using Xunit; + +#nullable disable + +namespace DynamicObjects { + public class M { + public const string ObjectRequiredMessage = "some string"; + public static int Main() { + var instance = createObject(); + var attrs = instance.GetType().GetProperty("prop1").GetCustomAttributes(); + + Assert.True(attrs.Count() == 2); + Assert.Equal(attrs.ElementAt(0).ToString(), "System.ComponentModel.DataAnnotations.DisplayAttribute"); + Assert.Equal(attrs.ElementAt(1).ToString(), "System.ComponentModel.DataAnnotations.RequiredAttribute"); + Assert.Equal(typeof(RequiredAttribute), attrs.ElementAt(1).GetType()); + Assert.Equal(ObjectRequiredMessage, ((RequiredAttribute)attrs.ElementAt(1)).FormatErrorMessage("abc")); + + Console.WriteLine("Success"); + return 100; + } + + public static object createObject () { + var an = new AssemblyName { Name = "TempAssembly" ,Version = new Version(1, 0, 0, 0) }; + var assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(an, AssemblyBuilderAccess.Run); + var moduleBuilder = assemblyBuilder.DefineDynamicModule("TempWorkflowAssembly.dll"); + var tb = moduleBuilder.DefineType("namespace.myclass" + , TypeAttributes.Public | + TypeAttributes.Class | + TypeAttributes.AnsiClass | + TypeAttributes.BeforeFieldInit + , typeof(object)); + + FieldBuilder fb = tb.DefineField("_prop1", + typeof(string), + FieldAttributes.Private); + + var pb = tb.DefineProperty("prop1", PropertyAttributes.HasDefault, typeof(string), null); + MethodAttributes getSetAttr = + MethodAttributes.Public | MethodAttributes.SpecialName | + MethodAttributes.HideBySig; + + // Define the "get" accessor method for prop1. + MethodBuilder custNameGetPropMthdBldr = + tb.DefineMethod("get_prop1", + getSetAttr, + typeof(string), + Type.EmptyTypes); + + ILGenerator custNameGetIL = custNameGetPropMthdBldr.GetILGenerator(); + + custNameGetIL.Emit(OpCodes.Ldarg_0); + custNameGetIL.Emit(OpCodes.Ldfld, fb); + custNameGetIL.Emit(OpCodes.Ret); + + // Define the "set" accessor method for prop1. + MethodBuilder custNameSetPropMthdBldr = + tb.DefineMethod("set_prop1", + getSetAttr, + null, + new Type[] { typeof(string) }); + + ILGenerator custNameSetIL = custNameSetPropMthdBldr.GetILGenerator(); + + custNameSetIL.Emit(OpCodes.Ldarg_0); + custNameSetIL.Emit(OpCodes.Ldarg_1); + custNameSetIL.Emit(OpCodes.Stfld, fb); + custNameSetIL.Emit(OpCodes.Ret); + + // Last, we must map the two methods created above to our PropertyBuilder to + // their corresponding behaviors, "get" and "set" respectively. + pb.SetGetMethod(custNameGetPropMthdBldr); + pb.SetSetMethod(custNameSetPropMthdBldr); + + + ///create display attribute + var dat = typeof(DisplayAttribute); + CustomAttributeBuilder CAB = new CustomAttributeBuilder(dat.GetConstructor(new Type[0]), + new object[0], + new PropertyInfo[1] { dat.GetProperty(nameof(DisplayAttribute.Name))}, + new object[] { "property 1"}); + pb.SetCustomAttribute(CAB); + + // //create required attribute + var rat = typeof(RequiredAttribute); + CustomAttributeBuilder CABR = new CustomAttributeBuilder(rat.GetConstructor(new Type[0]), + new object[0], + new PropertyInfo[2] { rat.GetProperty(nameof(RequiredAttribute.ErrorMessageResourceType)),rat.GetProperty(nameof(RequiredAttribute.ErrorMessageResourceName))}, + new object[] {typeof(ValidationErrors), "ObjectRequired" }); + pb.SetCustomAttribute(CABR); + + var objectType = tb.CreateType(); + return Activator.CreateInstance(objectType); + } + } + + public class ValidationErrors { + public static string ObjectRequired => M.ObjectRequiredMessage; + } + +} diff --git a/src/tests/Loader/CustomAttributes/DynamicObjects.csproj b/src/tests/Loader/CustomAttributes/DynamicObjects.csproj new file mode 100644 index 0000000000000..3e62bfd677e86 --- /dev/null +++ b/src/tests/Loader/CustomAttributes/DynamicObjects.csproj @@ -0,0 +1,9 @@ + + + Exe + + + + + + diff --git a/src/tests/issues.targets b/src/tests/issues.targets index 22178e4b3b506..bdccec81ac1f4 100644 --- a/src/tests/issues.targets +++ b/src/tests/issues.targets @@ -1177,6 +1177,10 @@ + + + Dynamic code generation is not supported on this platform +