public void CanAddAttribute() { var type = typeof (SomeClass); AssemblyName aName = new AssemblyName("SomeNamespace"); AssemblyBuilder ab = AppDomain.CurrentDomain.DefineDynamicAssembly(aName, AssemblyBuilderAccess.Run); ModuleBuilder mb = ab.DefineDynamicModule(aName.Name); TypeBuilder tb = mb.DefineType(type.Name, TypeAttributes.Public, type); TypeDescriptor.AddAttributes(type); Type[] attrCtorParams = {typeof (string)}; ConstructorInfo attrCtorInfo = typeof (DynamicAttribute).GetConstructor(attrCtorParams); if (attrCtorInfo != null) { CustomAttributeBuilder attrBuilder = new CustomAttributeBuilder(attrCtorInfo, new object[] {"Some Value"}); tb.SetCustomAttribute(attrBuilder); } Type newType = tb.CreateType(); SomeClass instance = (SomeClass) Activator.CreateInstance(newType); DynamicAttribute attr = (DynamicAttribute) instance.GetType().GetCustomAttributes(typeof (DynamicAttribute), false).SingleOrDefault(); Assert.AreEqual("Test", instance.Value); Assert.IsNotNull(attr); Assert.AreEqual(attr.Value, "Some Value"); }
public void SetCustomAttribute_CustomAttributeBuilder() { TypeBuilder type = Helpers.DynamicType(TypeAttributes.NotPublic); MethodBuilder method = type.DefineMethod("method1", MethodAttributes.Public | MethodAttributes.Static, typeof(void), new Type[] { typeof(int) }); ParameterBuilder parameter = method.DefineParameter(1, ParameterAttributes.HasDefault, "testParam"); ILGenerator ilGenerator = method.GetILGenerator(); ilGenerator.Emit(OpCodes.Ret); Type attributeType = typeof(ParameterBuilderCustomAttribute); ConstructorInfo constructor = attributeType.GetConstructors()[0]; FieldInfo field = attributeType.GetField("Field12345"); CustomAttributeBuilder attribute = new CustomAttributeBuilder(constructor, new object[] { 4 }, new FieldInfo[] { field }, new object[] { "hello" }); parameter.SetCustomAttribute(attribute); Type createdType = type.CreateTypeInfo().AsType(); MethodInfo createdMethod = createdType.GetMethod("method1"); ParameterInfo createdParameter = createdMethod.GetParameters()[0]; object[] attributes = createdParameter.GetCustomAttributes(false).ToArray(); Assert.Equal(1, attributes.Length); ParameterBuilderCustomAttribute obj = (ParameterBuilderCustomAttribute)attributes[0]; Assert.Equal("hello", obj.Field12345); Assert.Equal(4, obj.m_ctorType2); }
public void SetCustomAttribute() { Type returnType = typeof(int); Type[] ctorParamTypes = new Type[] { typeof(int) }; int expectedValue = 10; object[] ctorParamValues = new object[] { expectedValue }; CustomAttributeBuilder customAttrBuilder = new CustomAttributeBuilder(typeof(IntPropertyAttribute).GetConstructor(ctorParamTypes), ctorParamValues); TypeBuilder type = Helpers.DynamicType(TypeAttributes.Class | TypeAttributes.Public); PropertyBuilder property = type.DefineProperty("TestProperty", PropertyAttributes.HasDefault, returnType, null); property.SetCustomAttribute(customAttrBuilder); MethodAttributes getMethodAttributes = MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig; MethodBuilder method = type.DefineMethod("TestMethod", getMethodAttributes, returnType, new Type[0]); ILGenerator methodILGenerator = method.GetILGenerator(); methodILGenerator.Emit(OpCodes.Ldarg_0); methodILGenerator.Emit(OpCodes.Ret); property.SetGetMethod(method); BindingFlags bindingFlags = BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Static; Type createdType = type.CreateTypeInfo().AsType(); PropertyInfo createdProperty = createdType.GetProperty("TestProperty", bindingFlags); object[] attributes = createdProperty.GetCustomAttributes(false).ToArray(); Assert.Equal(1, attributes.Length); Assert.True(attributes[0] is IntPropertyAttribute); Assert.Equal(expectedValue, (attributes[0] as IntPropertyAttribute).Value); }
public void SetCustomAttribute(CustomAttributeBuilder customBuilder) { Universe u = this.Module.universe; if (customBuilder.Constructor.DeclaringType == u.System_Runtime_InteropServices_FieldOffsetAttribute) { customBuilder = customBuilder.DecodeBlob(this.Module.Assembly); SetOffset((int)customBuilder.GetConstructorArgument(0)); } else if (customBuilder.Constructor.DeclaringType == u.System_Runtime_InteropServices_MarshalAsAttribute) { MarshalSpec.SetMarshalAsAttribute(typeBuilder.ModuleBuilder, pseudoToken, customBuilder); attribs |= FieldAttributes.HasFieldMarshal; } else if (customBuilder.Constructor.DeclaringType == u.System_NonSerializedAttribute) { attribs |= FieldAttributes.NotSerialized; } else if (customBuilder.Constructor.DeclaringType == u.System_Runtime_CompilerServices_SpecialNameAttribute) { attribs |= FieldAttributes.SpecialName; } else { typeBuilder.ModuleBuilder.SetCustomAttribute(pseudoToken, customBuilder); } }
public void SetCustomAttribute_CustomAttributeBuilder() { TypeBuilder type = Helpers.DynamicType(TypeAttributes.Abstract); FieldBuilder field = type.DefineField("TestField", typeof(object), FieldAttributes.Public); ConstructorInfo attributeConstructor = typeof(EmptyAttribute).GetConstructor(new Type[0]); CustomAttributeBuilder attribute = new CustomAttributeBuilder(attributeConstructor, new object[0]); field.SetCustomAttribute(attribute); }
public void SetCustomAttribute_CustomAttributeBuilder() { TypeBuilder type = Helpers.DynamicType(TypeAttributes.Abstract); EventBuilder eventBuilder = type.DefineEvent("TestEvent", EventAttributes.None, typeof(TestEventHandler)); ConstructorInfo attributeConstructor = typeof(EmptyAttribute).GetConstructor(new Type[0]); CustomAttributeBuilder attribute = new CustomAttributeBuilder(attributeConstructor, new object[0]); eventBuilder.SetCustomAttribute(attribute); }
public void SetCustomAttribute_CustomAttributeBuilder_TypeCreated_ThrowsInvalidOperationException() { TypeBuilder type = Helpers.DynamicType(TypeAttributes.Abstract); FieldBuilder field = type.DefineField("TestField", typeof(object), FieldAttributes.Public); ConstructorInfo con = typeof(EmptyAttribute).GetConstructor(new Type[0]); CustomAttributeBuilder attribute = new CustomAttributeBuilder(con, new object[0]); type.CreateTypeInfo().AsType(); Assert.Throws<InvalidOperationException>(() => { field.SetCustomAttribute(attribute); }); }
public void SetCustomAttribute_CustomAttributeBuilder_TypeCreated_ThrowsInvalidOperationException() { TypeBuilder type = Helpers.DynamicType(TypeAttributes.Abstract); EventBuilder eventBuilder = type.DefineEvent("TestEvent", EventAttributes.None, typeof(TestEventHandler)); ConstructorInfo attributeConstructor = typeof(EmptyAttribute).GetConstructor(new Type[0]); CustomAttributeBuilder attribute = new CustomAttributeBuilder(attributeConstructor, new object[0]); type.CreateTypeInfo().AsType(); Assert.Throws<InvalidOperationException>(() => eventBuilder.SetCustomAttribute(attribute)); }
public void SetCustomAttribute_CustomAttributeBuilder() { TypeBuilder type = Helpers.DynamicType(TypeAttributes.Public); string[] typeParamNames = new string[] { "TFirst" }; GenericTypeParameterBuilder[] typeParams = type.DefineGenericParameters(typeParamNames); ConstructorInfo constructorinfo = typeof(HelperAttribute).GetConstructor(new Type[] { typeof(string) }); CustomAttributeBuilder attributeBuilder = new CustomAttributeBuilder(constructorinfo, new object[] { "TestString" }); typeParams[0].SetCustomAttribute(attributeBuilder); }
public void SetCustomAttribute_CustomAttributeBuilder() { ModuleBuilder module = Helpers.DynamicModule(); ConstructorInfo attributeConstructor = typeof(IntAllAttribute).GetConstructor(new Type[] { typeof(int) }); CustomAttributeBuilder attributeBuilder = new CustomAttributeBuilder(attributeConstructor, new object[] { 5 }); module.SetCustomAttribute(attributeBuilder); object[] attributes = module.GetCustomAttributes().ToArray(); Assert.Equal(1, attributes.Length); Assert.True(attributes[0] is IntAllAttribute); Assert.Equal(5, ((IntAllAttribute)attributes[0])._i); }
public void SetCustomAttribute_CustomAttributeBuilder_TypeNotCreated_ThrowsInvalidOperationException() { TypeBuilder type = Helpers.DynamicType(TypeAttributes.Class | TypeAttributes.Public); PropertyBuilder property = type.DefineProperty("TestProperty", PropertyAttributes.HasDefault, typeof(int), null); Type[] ctorParamTypes = new Type[] { typeof(int) }; object[] ctorParamValues = new object[] { 10 }; CustomAttributeBuilder customAttrBuilder = new CustomAttributeBuilder(typeof(IntPropertyAttribute).GetConstructor(ctorParamTypes), ctorParamValues); type.CreateTypeInfo().AsType(); Assert.Throws<InvalidOperationException>(() => property.SetCustomAttribute(customAttrBuilder)); }
public void SetCustomAttribute() { TypeBuilder type = Helpers.DynamicType(TypeAttributes.NotPublic); ConstructorInfo constructor = typeof(TypeBuilderStringAttribute).GetConstructor(new Type[] { typeof(string) }); CustomAttributeBuilder cuatbu = new CustomAttributeBuilder(constructor, new object[] { "hello" }); type.SetCustomAttribute(cuatbu); type.CreateTypeInfo().AsType(); object[] attributes = type.GetCustomAttributes(false).ToArray(); Assert.Equal(1, attributes.Length); Assert.True(attributes[0] is TypeBuilderStringAttribute); Assert.Equal("hello", ((TypeBuilderStringAttribute)attributes[0]).Creator); }
public void SetCustomAttribute(CustomAttributeBuilder customBuilder) { Universe u = typeBuilder.ModuleBuilder.universe; if (customBuilder.Constructor.DeclaringType == u.System_Runtime_CompilerServices_SpecialNameAttribute) { attributes |= EventAttributes.SpecialName; } else { if (lazyPseudoToken == 0) { lazyPseudoToken = typeBuilder.ModuleBuilder.AllocPseudoToken(); } typeBuilder.ModuleBuilder.SetCustomAttribute(lazyPseudoToken, customBuilder); } }
public void SetCustomAttribute_CustomAttributeBuilder() { TypeBuilder type = Helpers.DynamicType(TypeAttributes.NotPublic); Type attributeType = typeof(TypeBuilderIntAttribute); ConstructorInfo attriubteConstructor = attributeType.GetConstructors()[0]; FieldInfo attributeField = attributeType.GetField("Field12345"); CustomAttributeBuilder attribute = new CustomAttributeBuilder(attriubteConstructor, new object[] { 4 }, new FieldInfo[] { attributeField }, new object[] { "hello" }); type.SetCustomAttribute(attribute); type.CreateTypeInfo().AsType(); object[] attributes = type.GetCustomAttributes(false).ToArray(); Assert.Equal(1, attributes.Length); TypeBuilderIntAttribute obj = (TypeBuilderIntAttribute)attributes[0]; Assert.Equal("hello", obj.Field12345); Assert.Equal(4, obj.m_ctorType2); }
public void SetCustomAttribute_CustomAttributeBuilder() { TypeBuilder type = Helpers.DynamicType(TypeAttributes.Public); ConstructorBuilder constructor = type.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, new Type[0]); ILGenerator ilGenerator = constructor.GetILGenerator(); ilGenerator.Emit(OpCodes.Ldarg_1); ConstructorInfo attributeConstructor = typeof(IntAllAttribute).GetConstructor(new Type[] { typeof(int) }); CustomAttributeBuilder attributeBuilder = new CustomAttributeBuilder(attributeConstructor, new object[] { 2 }); constructor.SetCustomAttribute(attributeBuilder); Type createdType = type.CreateTypeInfo().AsType(); ConstructorInfo createdConstructor = createdType.GetConstructor(new Type[0]); Attribute[] customAttributes = createdConstructor.GetCustomAttributes(true).ToArray(); Assert.Equal(1, customAttributes.Length); Assert.Equal(2, ((IntAllAttribute)customAttributes[0])._i); }
internal void SetAttribute(CustomAttributeBuilder cab) { Universe u = cab.Constructor.Module.universe; Type type = cab.Constructor.DeclaringType; if (copyright == null && type == u.System_Reflection_AssemblyCopyrightAttribute) { copyright = (string)cab.GetConstructorArgument(0); } else if (trademark == null && type == u.System_Reflection_AssemblyTrademarkAttribute) { trademark = (string)cab.GetConstructorArgument(0); } else if (product == null && type == u.System_Reflection_AssemblyProductAttribute) { product = (string)cab.GetConstructorArgument(0); } else if (company == null && type == u.System_Reflection_AssemblyCompanyAttribute) { company = (string)cab.GetConstructorArgument(0); } else if (description == null && type == u.System_Reflection_AssemblyDescriptionAttribute) { description = (string)cab.GetConstructorArgument(0); } else if (title == null && type == u.System_Reflection_AssemblyTitleAttribute) { title = (string)cab.GetConstructorArgument(0); } else if (informationalVersion == null && type == u.System_Reflection_AssemblyInformationalVersionAttribute) { informationalVersion = (string)cab.GetConstructorArgument(0); } else if (culture == null && type == u.System_Reflection_AssemblyCultureAttribute) { culture = (string)cab.GetConstructorArgument(0); } else if (fileVersion == null && type == u.System_Reflection_AssemblyFileVersionAttribute) { fileVersion = (string)cab.GetConstructorArgument(0); } }
private static Type MyCreateCallee(AppDomain domain) { AssemblyName myAssemblyName = new AssemblyName(); myAssemblyName.Name = "EmittedAssembly"; // Define a dynamic assembly in the current application domain. AssemblyBuilder myAssembly = domain.DefineDynamicAssembly(myAssemblyName,AssemblyBuilderAccess.Run); // Define a dynamic module in this assembly. ModuleBuilder myModuleBuilder = myAssembly.DefineDynamicModule("EmittedModule"); // Construct a 'TypeBuilder' given the name and attributes. TypeBuilder myTypeBuilder = myModuleBuilder.DefineType("HelloWorld", TypeAttributes.Public); // Define a constructor of the dynamic class. ConstructorBuilder myConstructor = myTypeBuilder.DefineConstructor( MethodAttributes.Public, CallingConventions.Standard, new Type[]{typeof(String)}); ILGenerator myILGenerator = myConstructor.GetILGenerator(); myILGenerator.Emit(OpCodes.Ldstr, "Constructor is invoked"); myILGenerator.Emit(OpCodes.Ldarg_1); MethodInfo myMethodInfo = typeof(Console).GetMethod("WriteLine",new Type[]{typeof(string)}); myILGenerator.Emit(OpCodes.Call, myMethodInfo); myILGenerator.Emit(OpCodes.Ret); Type myType = typeof(MyAttribute); ConstructorInfo myConstructorInfo = myType.GetConstructor(new Type[]{typeof(object)}); try { CustomAttributeBuilder methodCABuilder = new CustomAttributeBuilder (myConstructorInfo, new object [] { TypeCode.Double } ); myConstructor.SetCustomAttribute(methodCABuilder); } catch(ArgumentNullException ex) { Console.WriteLine("The following exception has occured : "+ex.Message); } catch(Exception ex) { Console.WriteLine("The following exception has occured : "+ex.Message); } return myTypeBuilder.CreateType(); }
public void TestSetCustomAttribute1() { string name = "Assembly1"; AssemblyName asmname = new AssemblyName(); asmname.Name = name; AssemblyBuilder asmbuild = AssemblyBuilder.DefineDynamicAssembly(asmname, AssemblyBuilderAccess.Run); ModuleBuilder modbuild = TestLibrary.Utilities.GetModuleBuilder(asmbuild, "Module1"); TypeBuilder tpbuild = modbuild.DefineType("C1"); MethodBuilder methbuild = tpbuild.DefineMethod("method1", MethodAttributes.Public | MethodAttributes.Static, typeof(void), new Type[] { typeof(int) }); ParameterBuilder parambuild = methbuild.DefineParameter(1, ParameterAttributes.HasDefault, "testParam"); ILGenerator ilgen = methbuild.GetILGenerator(); ilgen.Emit(OpCodes.Ret); Type attrType = typeof(MBMyAttribute3); ConstructorInfo ci = attrType.GetConstructors()[0]; FieldInfo fi = attrType.GetField("Field12345"); CustomAttributeBuilder cab = new CustomAttributeBuilder(ci, new object[] { 4 }, new FieldInfo[] { fi }, new object[] { "hello" }); parambuild.SetCustomAttribute(cab); Type tp = tpbuild.CreateTypeInfo().AsType(); MethodInfo md = tp.GetMethod("method1"); ParameterInfo pi = md.GetParameters()[0]; // VERIFY object[] attribs = pi.GetCustomAttributes(false).Select(a => (object)a).ToArray(); Assert.Equal(1, attribs.Length); MBMyAttribute3 obj = (MBMyAttribute3)attribs[0]; Assert.Equal("hello", obj.Field12345); Assert.Equal(4, obj.m_ctorType2); }
public void SetCustomAttribute_CustomAttributeBuilder() { TypeBuilder type = Helpers.DynamicType(TypeAttributes.NotPublic); MethodBuilder method = type.DefineMethod("TestMethod", MethodAttributes.Public | MethodAttributes.Static); ILGenerator ilgen = method.GetILGenerator(); ilgen.Emit(OpCodes.Ldc_I4, 100); ilgen.Emit(OpCodes.Ret); Type attributeType = typeof(MethodBuilderCustomIntAttribute); ConstructorInfo constructor = attributeType.GetConstructors()[0]; FieldInfo field = attributeType.GetField("Field12345"); CustomAttributeBuilder attribute = new CustomAttributeBuilder(constructor, new object[] { 4 }, new FieldInfo[] { field }, new object[] { "hello" }); method.SetCustomAttribute(attribute); Type createdType = type.CreateTypeInfo().AsType(); object[] attributes = createdType.GetMethod("TestMethod").GetCustomAttributes(false).ToArray(); Assert.Equal(1, attributes.Length); MethodBuilderCustomIntAttribute obj = (MethodBuilderCustomIntAttribute)attributes[0]; Assert.Equal("hello", obj.Field12345); Assert.Equal(4, obj._intField); }
public void CtorFourTest() { //test for the constructor with signature-- //public CustomAttributeBuilder(ConstructorInfo, object[], PropertyInfo[], object[], FieldInfo[], object[]); /* * WE build a imaginary type as follows * [CustomAttribute()] * public class TestType * { * * } * We also set the "AttributeOne" property , * and "Feild" of class CustomAttribute * by means of the constuctor of CustomAttributeBuilder * And then check for the validity */ AssemblyName asmName = new AssemblyName(); asmName.Name = "TestAssembly.dll"; AssemblyBuilder asmBuilder = Thread.GetDomain().DefineDynamicAssembly( asmName, AssemblyBuilderAccess.Run); ModuleBuilder modBuilder = asmBuilder.DefineDynamicModule("TestModule"); TypeBuilder typeBuilder = modBuilder.DefineType("TestType", TypeAttributes.Public); Type [] ctorParams = new Type [] { }; ConstructorInfo classCtorInfo = typeof(CustomAttribute).GetConstructor(ctorParams); CustomAttributeBuilder typeCABuilder = new CustomAttributeBuilder( classCtorInfo, new object [] { }, new PropertyInfo [] { typeof(CustomAttribute).GetProperty("AttributeOne") }, new object [] { "TestCase" }, typeof(CustomAttribute).GetFields(), new object [] { "FieldValue" } ); typeBuilder.SetCustomAttribute(typeCABuilder); // create the type Type myType = typeBuilder.CreateType(); //Now check for the validity of the attributes. object testInstance = Activator.CreateInstance(myType); //check the validity of the attribute associated with Print method object [] customAttrs = myType.GetCustomAttributes(false); Assert.AreEqual(customAttrs.Length, 1, "#1"); //Custom Attributes of TestType CustomAttribute attr = customAttrs [0] as CustomAttribute; Assert.AreEqual(attr.AttributeOne, "TestCase", "#2"); Assert.AreEqual(attr.Feild, "FieldValue", "#3"); }
public void CtorOneTest() { //test for the constructor with signature-- // public CustomAttributeBuilder(ConstructorInfo, object[]); /* * WE build a imaginary type as follows * class TestType * { * [CustomAttribute("one","two")] * public string Str; * * [CustomAttribute("hello","world")] * public void Print() * {Console.WriteLine("Hello World"); } * * } * And then check for the validity of attributes in the test functions */ AssemblyName asmName = new AssemblyName(); asmName.Name = "TestAssembly.dll"; AssemblyBuilder asmBuilder = Thread.GetDomain().DefineDynamicAssembly( asmName, AssemblyBuilderAccess.Run); ModuleBuilder modBuilder = asmBuilder.DefineDynamicModule("TestModule"); TypeBuilder typeBuilder = modBuilder.DefineType("TestType", TypeAttributes.Public); Type[] ctorParams = new Type[] { typeof(string), typeof(string) }; ConstructorInfo classCtorInfo = typeof(CustomAttribute).GetConstructor(ctorParams); CustomAttributeBuilder feildCABuilder = new CustomAttributeBuilder( classCtorInfo, new object [] { "one", "two" } ), methodCABuilder = new CustomAttributeBuilder( classCtorInfo, new object [] { "hello", "world" } ); //now let's build a feild of type string and associate a attribute with it FieldBuilder fieldBuilder = typeBuilder.DefineField("Str", typeof(string), FieldAttributes.Public); fieldBuilder.SetCustomAttribute(feildCABuilder); //now build a method MethodBuilder methodBuilder = typeBuilder.DefineMethod("Print", MethodAttributes.Public, null, null); methodBuilder.SetCustomAttribute(methodCABuilder); ILGenerator methodIL = methodBuilder.GetILGenerator(); methodIL.EmitWriteLine("Hello, world!"); methodIL.Emit(OpCodes.Ret); // create the type Type myType = typeBuilder.CreateType(); //Now check for the validity of the attributes. object testInstance = Activator.CreateInstance(myType); //check the validity of the attribute associated with Print method object [] methodAttrs = myType.GetMember("Print") [0].GetCustomAttributes(true); Assert.AreEqual(methodAttrs.Length, 1, "#1"); CustomAttribute methodAttr = methodAttrs [0] as CustomAttribute; Assert.AreEqual(methodAttr.AttributeOne, "hello", "#2"); Assert.AreEqual(methodAttr.AttributeTwo, "world", "#3"); //check the validity of the attribute associated with Str feild object [] fieldAttrs = myType.GetField("Str").GetCustomAttributes(true); Assert.AreEqual(fieldAttrs.Length, 1, "#4"); CustomAttribute fieldAttr = fieldAttrs [0] as CustomAttribute; Assert.AreEqual(fieldAttr.AttributeOne, "one", "#5"); Assert.AreEqual(fieldAttr.AttributeTwo, "two", "#6"); }
static void BuildMethod( TypeBuilder tb, string methodName, string rpcMethodName, string[] paramNames, Type[] argTypes, bool paramsMethod, Type returnType, bool structParams) { MethodBuilder mthdBldr = tb.DefineMethod( methodName, MethodAttributes.Public | MethodAttributes.Virtual, returnType, argTypes); // add attribute to method Type[] oneString = new Type[1] { typeof(string) }; Type methodAttr = typeof(XmlRpcMethodAttribute); ConstructorInfo ci = methodAttr.GetConstructor(oneString); PropertyInfo[] pis = new PropertyInfo[] { methodAttr.GetProperty("StructParams") }; object[] structParam = new object[] { structParams }; CustomAttributeBuilder cab = new CustomAttributeBuilder(ci, new object[] { rpcMethodName }, pis, structParam); mthdBldr.SetCustomAttribute(cab); for (int i = 0; i < paramNames.Length; i++) { ParameterBuilder paramBldr = mthdBldr.DefineParameter(i + 1, ParameterAttributes.In, paramNames[i]); // possibly add ParamArrayAttribute to final parameter if (i == paramNames.Length - 1 && paramsMethod) { ConstructorInfo ctorInfo = typeof(ParamArrayAttribute).GetConstructor( new Type[0]); CustomAttributeBuilder attrBldr = new CustomAttributeBuilder(ctorInfo, new object[0]); paramBldr.SetCustomAttribute(attrBldr); } } // generate IL ILGenerator ilgen = mthdBldr.GetILGenerator(); // if non-void return, declared locals for processing return value LocalBuilder retVal = null; LocalBuilder tempRetVal = null; if (typeof(void) != returnType) { tempRetVal = ilgen.DeclareLocal(typeof(System.Object)); retVal = ilgen.DeclareLocal(returnType); } // declare variable to store method args and emit code to populate ut LocalBuilder argValues = ilgen.DeclareLocal(typeof(System.Object[])); ilgen.Emit(OpCodes.Ldc_I4, argTypes.Length); ilgen.Emit(OpCodes.Newarr, typeof(System.Object)); ilgen.Emit(OpCodes.Stloc, argValues); for (int argLoad = 0; argLoad < argTypes.Length; argLoad++) { ilgen.Emit(OpCodes.Ldloc, argValues); ilgen.Emit(OpCodes.Ldc_I4, argLoad); ilgen.Emit(OpCodes.Ldarg, argLoad + 1); if (argTypes[argLoad].IsValueType) { ilgen.Emit(OpCodes.Box, argTypes[argLoad]); } ilgen.Emit(OpCodes.Stelem_Ref); } // call Invoke on base class Type[] invokeTypes = new Type[] { typeof(MethodInfo), typeof(object[]) }; MethodInfo invokeMethod = typeof(XmlRpcClientProtocol).GetMethod("Invoke", invokeTypes); ilgen.Emit(OpCodes.Ldarg_0); ilgen.Emit(OpCodes.Call, typeof(MethodBase).GetMethod("GetCurrentMethod")); ilgen.Emit(OpCodes.Castclass, typeof(System.Reflection.MethodInfo)); ilgen.Emit(OpCodes.Ldloc, argValues); ilgen.Emit(OpCodes.Call, invokeMethod); // if non-void return prepare return value, otherwise pop to discard if (typeof(void) != returnType) { // if return value is null, don't cast it to required type Label retIsNull = ilgen.DefineLabel(); ilgen.Emit(OpCodes.Stloc, tempRetVal); ilgen.Emit(OpCodes.Ldloc, tempRetVal); ilgen.Emit(OpCodes.Brfalse, retIsNull); ilgen.Emit(OpCodes.Ldloc, tempRetVal); if (true == returnType.IsValueType) { ilgen.Emit(OpCodes.Unbox, returnType); ilgen.Emit(OpCodes.Ldobj, returnType); } else { ilgen.Emit(OpCodes.Castclass, returnType); } ilgen.Emit(OpCodes.Stloc, retVal); ilgen.MarkLabel(retIsNull); ilgen.Emit(OpCodes.Ldloc, retVal); } else { ilgen.Emit(OpCodes.Pop); } ilgen.Emit(OpCodes.Ret); }
public void SetCustomAttribute(CustomAttributeBuilder customBuilder);
/// <summary> /// Generates an AOT DLL, using the given parameters. /// </summary> public static void GenerateDLL(string dirPath, string assemblyName, List <Type> supportSerializedTypes, bool generateLinkXml = true) { if (!dirPath.EndsWith("/")) { dirPath += "/"; } var newDllPath = dirPath + assemblyName; var fullDllPath = newDllPath + ".dll"; var assembly = AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName() { Name = assemblyName }, AssemblyBuilderAccess.Save, dirPath); var module = assembly.DefineDynamicModule(assemblyName); assembly.SetCustomAttribute(new CustomAttributeBuilder(typeof(EmittedAssemblyAttribute).GetConstructor(new Type[0]), new object[0])); // The following is a fix for Unity's crappy Mono runtime that doesn't know how to do this sort // of stuff properly // // We must manually remove the "Default Dynamic Assembly" module that is automatically defined, // otherwise a reference to that non-existent module will be saved into the assembly's IL, and // that will cause a multitude of issues. // // We do this by forcing there to be only one module - the one we just defined, and we set the // manifest module to be that module as well. { var modulesField = assembly.GetType().GetField("modules", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); var manifestModuleField = assembly.GetType().GetField("manifest_module", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); if (modulesField != null) { modulesField.SetValue(assembly, new ModuleBuilder[] { module }); } if (manifestModuleField != null) { manifestModuleField.SetValue(assembly, module); } } var type = module.DefineType(assemblyName + ".PreventCodeStrippingViaReferences", TypeAttributes.Abstract | TypeAttributes.Sealed | TypeAttributes.NotPublic); CustomAttributeBuilder attributeBuilder = new CustomAttributeBuilder(typeof(PreserveAttribute).GetConstructor(Type.EmptyTypes), new object[0]); type.SetCustomAttribute(attributeBuilder); var staticConstructor = type.DefineTypeInitializer(); var il = staticConstructor.GetILGenerator(); var falseLocal = il.DeclareLocal(typeof(bool)); il.Emit(OpCodes.Ldc_I4_0); // Load false il.Emit(OpCodes.Stloc, falseLocal); // Set to falseLocal HashSet <Type> seenTypes = new HashSet <Type>(); if (UnityVersion.Major == 2019 && UnityVersion.Minor == 2) { // This here is a hack that fixes Unity's assembly updater triggering faultily in Unity 2019.2 // (and in early 2019.3 alphas/betas, but we're not handling those). When it triggers, it edits // the generated AOT assembly such that it immediately causes Unity to hard crash. Having this // type reference present in the assembly prevents that from happening. (Any concrete type in // the serialization assembly would work, this one is just a random pick.) // // Unity should have fixed this in 2019.3, but said that a backport to 2019.2 is not guaranteed // to occur, though it might. supportSerializedTypes.Add(typeof(DateTimeFormatter)); } //var endPoint = il.DefineLabel(); //il.Emit(OpCodes.Br, endPoint); foreach (var serializedType in supportSerializedTypes) { if (serializedType == null) { continue; } bool isAbstract = serializedType.IsAbstract || serializedType.IsInterface; if (serializedType.IsGenericType && (serializedType.IsGenericTypeDefinition || !serializedType.IsFullyConstructedGenericType())) { Debug.LogError("Skipping type '" + serializedType.GetNiceFullName() + "'! Type is a generic type definition, or its arguments contain generic parameters; type must be a fully constructed generic type."); continue; } if (seenTypes.Contains(serializedType)) { continue; } seenTypes.Add(serializedType); // Reference serialized type { if (serializedType.IsValueType) { var local = il.DeclareLocal(serializedType); il.Emit(OpCodes.Ldloca, local); il.Emit(OpCodes.Initobj, serializedType); } else if (!isAbstract) { var constructor = serializedType.GetConstructor(Type.EmptyTypes); if (constructor != null) { il.Emit(OpCodes.Newobj, constructor); il.Emit(OpCodes.Pop); } } } // Reference and/or create formatter type if (!FormatterUtilities.IsPrimitiveType(serializedType) && !typeof(UnityEngine.Object).IsAssignableFrom(serializedType) && !isAbstract) { var actualFormatter = FormatterLocator.GetFormatter(serializedType, SerializationPolicies.Unity); if (actualFormatter.GetType().IsDefined <EmittedFormatterAttribute>()) { //TODO: Make emitted formatter code compatible with IL2CPP //// Emit an actual AOT formatter into the generated assembly //if (this.emitAOTFormatters) //{ // var emittedFormatter = FormatterEmitter.EmitAOTFormatter(typeEntry.Type, module, SerializationPolicies.Unity); // var emittedFormatterConstructor = emittedFormatter.GetConstructor(Type.EmptyTypes); // il.Emit(OpCodes.Newobj, emittedFormatterConstructor); // il.Emit(OpCodes.Pop); //} } var formatters = FormatterLocator.GetAllCompatiblePredefinedFormatters(serializedType, SerializationPolicies.Unity); foreach (var formatter in formatters) { // Reference the pre-existing formatter var formatterConstructor = formatter.GetType().GetConstructor(Type.EmptyTypes); if (formatterConstructor != null) { il.Emit(OpCodes.Newobj, formatterConstructor); il.Emit(OpCodes.Pop); } } //// Make sure we have a proper reflection formatter variant if all else goes wrong //il.Emit(OpCodes.Newobj, typeof(ReflectionFormatter<>).MakeGenericType(serializedType).GetConstructor(Type.EmptyTypes)); //il.Emit(OpCodes.Pop); } ConstructorInfo serializerConstructor; // Reference serializer variant if (serializedType.IsValueType) { serializerConstructor = Serializer.Get(serializedType).GetType().GetConstructor(Type.EmptyTypes); il.Emit(OpCodes.Newobj, serializerConstructor); // The following section is a fix for an issue on IL2CPP for PS4, where sometimes bytecode isn't // generated for methods in base types of needed types - FX, Serializer<T>.ReadValueWeak() // may be missing. This only seems to happen in a relevant way for value types. { var endLabel = il.DefineLabel(); // Load a false local value, then jump to the end of this segment of code due to that // false value. This is an attempt to trick any potential code flow analysis made // by IL2CPP that checks whether this segment of code is actually run. // // We don't run the code because if we did, that would actually throw a bunch of // exceptions from invalid calls to ReadValueWeak and WriteValueWeak. il.Emit(OpCodes.Ldloc, falseLocal); il.Emit(OpCodes.Brfalse, endLabel); var baseSerializerType = typeof(Serializer <>).MakeGenericType(serializedType); var readValueWeakMethod = baseSerializerType.GetMethod("ReadValueWeak", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly, null, new Type[] { typeof(IDataReader) }, null); var writeValueWeakMethod = baseSerializerType.GetMethod("WriteValueWeak", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly, null, new Type[] { typeof(string), typeof(object), typeof(IDataWriter) }, null); il.Emit(OpCodes.Dup); // Duplicate serializer instance il.Emit(OpCodes.Ldnull); // Load null argument for IDataReader reader il.Emit(OpCodes.Callvirt, readValueWeakMethod); // Call ReadValueWeak on serializer instance il.Emit(OpCodes.Pop); // Pop result of ReadValueWeak il.Emit(OpCodes.Dup); // Duplicate serializer instance il.Emit(OpCodes.Ldnull); // Load null argument for string name il.Emit(OpCodes.Ldnull); // Load null argument for object value il.Emit(OpCodes.Ldnull); // Load null argument for IDataWriter writer il.Emit(OpCodes.Callvirt, writeValueWeakMethod); // Call WriteValueWeak on serializer instance il.MarkLabel(endLabel); // This is where the code always jumps to, skipping the above } il.Emit(OpCodes.Pop); // Pop the serializer instance } else { serializerConstructor = typeof(ComplexTypeSerializer <>).MakeGenericType(serializedType).GetConstructor(Type.EmptyTypes); il.Emit(OpCodes.Newobj, serializerConstructor); il.Emit(OpCodes.Pop); } } //il.MarkLabel(endPoint); il.Emit(OpCodes.Ret); type.CreateType(); if (!Directory.Exists(dirPath)) { Directory.CreateDirectory(dirPath); } if (File.Exists(fullDllPath)) { File.Delete(fullDllPath); } if (File.Exists(fullDllPath + ".meta")) { File.Delete(fullDllPath + ".meta"); } try { AssetDatabase.Refresh(); } catch (Exception) { // Sigh, Unity 5.3.0 } assembly.Save(assemblyName); File.Move(newDllPath, fullDllPath); if (generateLinkXml) { File.WriteAllText(dirPath + "link.xml", @"<linker> <assembly fullname=""" + assemblyName + @""" preserve=""all""/> </linker>"); } try { AssetDatabase.Refresh(); } catch (Exception) { // Sigh, Unity 5.3.0 } var pluginImporter = PluginImporter.GetAtPath(fullDllPath) as PluginImporter; if (pluginImporter != null) { //pluginImporter.ClearSettings(); pluginImporter.SetCompatibleWithEditor(false); pluginImporter.SetCompatibleWithAnyPlatform(true); // Disable for all standalones pluginImporter.SetCompatibleWithPlatform(BuildTarget.StandaloneLinux64, false); if (!UnityVersion.IsVersionOrGreater(2019, 2)) { pluginImporter.SetCompatibleWithPlatform((BuildTarget)17, false); // StandaloneLinux pluginImporter.SetCompatibleWithPlatform((BuildTarget)25, false); // StandaloneLinuxUniversal } // StandaloneOSXUniversal (<= 2017.2) / StandaloneOSX (>= 2017.3) pluginImporter.SetCompatibleWithPlatform((BuildTarget)2, false); if (!UnityVersion.IsVersionOrGreater(2017, 3)) { pluginImporter.SetCompatibleWithPlatform((BuildTarget)4, false); // StandaloneOSXIntel pluginImporter.SetCompatibleWithPlatform((BuildTarget)27, false); // StandaloneOSXIntel64 } pluginImporter.SetCompatibleWithPlatform(BuildTarget.StandaloneWindows, false); pluginImporter.SetCompatibleWithPlatform(BuildTarget.StandaloneWindows64, false); //pluginImporter.SetCompatibleWithPlatform(BuildTarget.Android, false); pluginImporter.SaveAndReimport(); } AssetDatabase.SaveAssets(); }
public void DefineCustomAttribute(CustomAttributeBuilder attribute) { builder.SetCustomAttribute(attribute); }
/// <summary> /// 将一个类型动态生成另一个子类,并在其继承的接口上打上[ServiceContract]标记 /// </summary> /// <param name="sourceType"></param> /// <returns></returns> public static Type Wrapper(Type sourceType) { AppDomain myCurrentDomain = AppDomain.CurrentDomain; AssemblyName myAssemblyName;//= new AssemblyName(); myAssemblyName = sourceType.Assembly.GetName(); System.Reflection.Emit.AssemblyBuilder myAssemblyBuilder = myCurrentDomain.DefineDynamicAssembly (myAssemblyName, AssemblyBuilderAccess.Run); ModuleBuilder myModuleBuilder = myAssemblyBuilder. DefineDynamicModule("TempModule"); Type[] interfaces = sourceType.GetInterfaces(); Type[] ExtInterfaces = new Type[interfaces.Count()]; int index = 0; foreach (Type aInterface in interfaces) { TypeBuilder ExtInterfaceTypeBuilder = myModuleBuilder.DefineType (aInterface.Name + suffix, TypeAttributes.Public | TypeAttributes.Interface | TypeAttributes.Abstract); var methods = aInterface.GetMethods(); foreach (var method in methods) { var aparams = method.GetParameters(); Type[] param = new Type[aparams.Count()]; for (int i = 0; i < aparams.Count(); i++) { param[i] = aparams[i].ParameterType; } var methodBuilder = ExtInterfaceTypeBuilder.DefineMethod(method.Name, method.Attributes, CallingConventions.Standard, method.ReturnType, param); for (int i = 0; i < aparams.Count(); i++) { if (aparams[i].IsOut)///TODO:其他参数属性处理,目前仅处理(Out),其他视为None { methodBuilder.DefineParameter(1, ParameterAttributes.Out, aparams[i].Name); } else { methodBuilder.DefineParameter(1, ParameterAttributes.None, aparams[i].Name); } } ConstructorInfo cinfo = typeof(OperationContractAttribute).GetConstructors()[0]; CustomAttributeBuilder caBuilder = new CustomAttributeBuilder(cinfo, new object[] { }); methodBuilder.SetCustomAttribute(caBuilder); } var acinfo = typeof(ServiceContractAttribute).GetConstructors()[0]; var acaBuilder = new CustomAttributeBuilder(acinfo, new object[] { }); ExtInterfaces[index++] = ExtInterfaceTypeBuilder.CreateType(); ExtInterfaceTypeBuilder.SetCustomAttribute(acaBuilder); } TypeBuilder ExtClassTypeBuilder = myModuleBuilder.DefineType (sourceType.Name + suffix, TypeAttributes.Public, sourceType, ExtInterfaces); Type rType = ExtClassTypeBuilder.CreateType(); return(rType); }
public static Type GenerateTypeFromGridColumn(string gridName) { // create a dynamic assembly and module AssemblyName assemblyName = new AssemblyName(); assemblyName.Name = "tmpAssembly"; AssemblyBuilder assemblyBuilder = System.Threading.Thread.GetDomain().DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run); ModuleBuilder module = assemblyBuilder.DefineDynamicModule("tmpModule"); // create a new type builder TypeBuilder typeBuilder = module.DefineType(gridName, TypeAttributes.Public | TypeAttributes.Class | TypeAttributes.Class | TypeAttributes.AutoClass | TypeAttributes.AnsiClass | TypeAttributes.BeforeFieldInit | TypeAttributes.AutoLayout, null, new Type[] { typeof(IEntity) }); { DataContractAttribute dca = new DataContractAttribute(); ConstructorInfo ctor = typeof(DataContractAttribute).GetConstructor(new Type[] { }); CustomAttributeBuilder myCABuilder = new CustomAttributeBuilder(ctor, new object[] { }, new PropertyInfo[] { typeof(DataContractAttribute).GetProperty("Name") }, new object[] { gridName }); typeBuilder.SetCustomAttribute(myCABuilder); } int idx = 0; // Loop over the attributes that will be used as the properties names in out new type foreach (GridColumnInfo info in ADInfoBll.Instance.GetGridColumnInfos(gridName)) { if (info.GridColumnType != GridColumnType.Normal && info.GridColumnType != GridColumnType.ExpressionColumn) { continue; } string propertyName = info.GridColumnName; Type propertyType = typeof(string); //Type propertyType = info.CreateType(); //if (propertyType.IsEnum || propertyType.IsClass || info.CellViewerManager == "Combo") //{ // propertyType = typeof(string); //} //if (!propertyType.IsClass/* && Authority.AuthorizeByRule(info.NotNull)*/) //{ // propertyType = Utils.ReflectionHelper.CreateGenericType(typeof(Nullable<>), new Type[] { propertyType }); //} // Generate a private field FieldBuilder field = typeBuilder.DefineField("_" + propertyName, propertyType, FieldAttributes.Private); // Generate a public property PropertyBuilder property = typeBuilder.DefineProperty(propertyName, PropertyAttributes.HasDefault, propertyType, null); // The property set and property get methods require a special set of attributes: MethodAttributes GetSetAttr = MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig; // Define the "get" accessor method for current private field. MethodBuilder currGetPropMthdBldr = typeBuilder.DefineMethod("get_" + propertyName, GetSetAttr, propertyType, Type.EmptyTypes); // Intermediate Language stuff... ILGenerator currGetIL = currGetPropMthdBldr.GetILGenerator(); currGetIL.Emit(OpCodes.Ldarg_0); currGetIL.Emit(OpCodes.Ldfld, field); currGetIL.Emit(OpCodes.Ret); // Define the "set" accessor method for current private field. MethodBuilder currSetPropMthdBldr = typeBuilder.DefineMethod("set_" + propertyName, GetSetAttr, null, new Type[] { propertyType }); // Again some Intermediate Language stuff... ILGenerator currSetIL = currSetPropMthdBldr.GetILGenerator(); currSetIL.Emit(OpCodes.Ldarg_0); currSetIL.Emit(OpCodes.Ldarg_1); currSetIL.Emit(OpCodes.Stfld, field); currSetIL.Emit(OpCodes.Ret); // Last, we must map the two methods created above to our PropertyBuilder to // their corresponding behaviors, "get" and "set" respectively. property.SetGetMethod(currGetPropMthdBldr); property.SetSetMethod(currSetPropMthdBldr); DataMemberAttribute dca = new DataMemberAttribute(); ConstructorInfo ctor = typeof(DataMemberAttribute).GetConstructor(new Type[] { }); CustomAttributeBuilder myCABuilder = new CustomAttributeBuilder(ctor, new object[] { }, new PropertyInfo[] { typeof(DataMemberAttribute).GetProperty("Name"), typeof(DataMemberAttribute).GetProperty("Order") }, new object[] { propertyName, idx }); property.SetCustomAttribute(myCABuilder); idx++; } // Generate our type Type generetedType = typeBuilder.CreateType(); return(generetedType); }
private static Type ImplementMethodDelegate(string assemblyName, ModuleBuilder moduleBuilder, MethodItem method) { // Consts const MethodAttributes methodAttributes = MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.Virtual; // Initial var delegateName = GetDelegateName(assemblyName, method.Info); var delegateBuilder = moduleBuilder.DefineType(delegateName, TypeAttributes.Public | TypeAttributes.AutoClass | TypeAttributes.Sealed, typeof(MulticastDelegate)); // UnmanagedFunctionPointer var importAttribute = method.DllImportAttribute; var attributeCtor = typeof(UnmanagedFunctionPointerAttribute).GetConstructor(new[] { typeof(CallingConvention) }); if (attributeCtor == null) { throw new Exception("There is no the target constructor of the UnmanagedFunctionPointerAttribute"); } var attributeBuilder = new CustomAttributeBuilder(attributeCtor, new object[] { importAttribute.CallingConvention }, new[] { typeof(UnmanagedFunctionPointerAttribute).GetField("CharSet"), typeof(UnmanagedFunctionPointerAttribute).GetField("BestFitMapping"), typeof(UnmanagedFunctionPointerAttribute).GetField("ThrowOnUnmappableChar"), typeof(UnmanagedFunctionPointerAttribute).GetField("SetLastError") }, new object[] { importAttribute.CharSet, importAttribute.BestFitMapping, importAttribute.ThrowOnUnmappableChar, importAttribute.SetLastError }); delegateBuilder.SetCustomAttribute(attributeBuilder); // ctor var ctorBuilder = delegateBuilder.DefineConstructor(MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName, CallingConventions.Standard, new[] { typeof(object), typeof(IntPtr) }); ctorBuilder.SetImplementationFlags(MethodImplAttributes.CodeTypeMask); ctorBuilder.DefineParameter(1, ParameterAttributes.HasDefault, "object"); ctorBuilder.DefineParameter(2, ParameterAttributes.HasDefault, "method"); // Invoke var parameters = GetParameterInfoArray(method.Info); var methodBuilder = DefineMethod(delegateBuilder, "Invoke", methodAttributes, method.ReturnType, parameters); methodBuilder.SetImplementationFlags(MethodImplAttributes.CodeTypeMask); // BeginInvoke parameters = GetParameterInfoArray(method.Info, InfoArrayMode.BeginInvoke); methodBuilder = DefineMethod(delegateBuilder, "BeginInvoke", methodAttributes, typeof(IAsyncResult), parameters); methodBuilder.SetImplementationFlags(MethodImplAttributes.CodeTypeMask); // EndInvoke parameters = GetParameterInfoArray(method.Info, InfoArrayMode.EndInvoke); methodBuilder = DefineMethod(delegateBuilder, "EndInvoke", methodAttributes, method.ReturnType, parameters); methodBuilder.SetImplementationFlags(MethodImplAttributes.CodeTypeMask); // Create type return(delegateBuilder.CreateType()); }
/// <summary> /// 生成一个接口的代理类,并从baseType继承 /// </summary> /// <param name="targetType">接口类型</param> /// <returns>代理类</returns> public static Type CreateSerializeableProxyType(Type targetType, Type baseType, bool igoreCrossDomainAttribute = false, Action <TypeBuilder> onTypeCreator = null ) { if (!targetType.IsInterface) { throw new ArgumentException("必须是接口", "targetType"); } if (!typeof(ISerializable).IsAssignableFrom(baseType)) { throw new ArgumentException("基类必须实现 ISerializable"); } Debug.Assert(targetType.IsInterface, "必须是接口"); //Type baseType = typeof(SerializableMarshalByRefObject<>).MakeGenericType(targetType); AssemblyName assemblyName = new AssemblyName(string.Concat("SerializeableProxyType_", string.Concat(targetType.GUID.ToString("N"), baseType.GUID.ToString("N")).ComputeMd5())); var assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.RunAndSave); var module = assemblyBuilder.DefineDynamicModule(assemblyName.Name, string.Concat(assemblyName.Name, ".dll")); //声明类 string typeName = string.Concat(targetType.FullName, "_", baseType.Name, "_SerializeableProxy"); var typeBuilder = module.DefineType(typeName, TypeAttributes.Public | TypeAttributes.Class | TypeAttributes.Sealed, baseType, new Type[] { targetType }); // //添加 SerializableAttribute ConstructorInfo classCtorInfo = typeof(SerializableAttribute).GetConstructor(new Type[0]); CustomAttributeBuilder caBuilder = new CustomAttributeBuilder(classCtorInfo, new object[0]); typeBuilder.SetCustomAttribute(caBuilder); //实现类 //字段 var fieldTarget = baseType.GetField("target", BindingFlags.Instance | BindingFlags.NonPublic); //fieldBuilder.SetConstant(null); foreach (var cnst in baseType.GetConstructors(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)) { var parmInfos = cnst.GetParameters(); var parmTypes = parmInfos.ToList().ConvertAll(pi => pi.ParameterType).ToArray(); var cnstBuilder = typeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, parmTypes); { var il = cnstBuilder.GetILGenerator(); il.Emit(OpCodes.Ldarg_0); for (int i = 1; i <= parmTypes.Length; ++i) { switch (i) { case 0: il.Emit(OpCodes.Ldarg_0); break; case 1: il.Emit(OpCodes.Ldarg_1); break; case 2: il.Emit(OpCodes.Ldarg_2); break; case 3: il.Emit(OpCodes.Ldarg_3); break; default: il.Emit(OpCodes.Ldarg_S, (byte)i); break; } } //il.Emit(OpCodes.Stfld, fieldBuilder); il.Emit(OpCodes.Call, cnst); il.Emit(OpCodes.Ret); } } ////构造函数 //var cnstBuilder = typeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, new Type[] { targetType }); //{ // var il = cnstBuilder.GetILGenerator(); // il.Emit(OpCodes.Ldarg_0); // il.Emit(OpCodes.Ldarg_1); // //il.Emit(OpCodes.Stfld, fieldBuilder); // il.Emit(OpCodes.Call, baseType.GetConstructor(new[] { targetType })); // il.Emit(OpCodes.Ret); //} //var cnstSeriaBuilder = typeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, new Type[] { typeof(SerializationInfo), typeof(StreamingContext ) }); //{ // var il = cnstSeriaBuilder.GetILGenerator(); // il.Emit(OpCodes.Ldarg_0); // il.Emit(OpCodes.Ldarg_1); // il.Emit(OpCodes.Ldarg_2); // il.Emit(OpCodes.Call, baseType.GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, null, new Type[] { typeof(SerializationInfo), typeof(StreamingContext) }, null)); // il.Emit(OpCodes.Ret); //} //属性 Dictionary <MethodInfo, MethodBuilder> map = new Dictionary <MethodInfo, MethodBuilder>(); //方法代理 List <MethodInfo> methods = new List <MethodInfo>(); methods.AddRange(targetType.GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly)); foreach (var tt in targetType.GetInterfaces()) { methods.AddRange(tt.GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly)); } methods.ForEach(mi => { var retType = mi.ReturnType; var parmInfos = mi.GetParameters(); var parmTypes = parmInfos.ToList().ConvertAll(pi => pi.ParameterType).ToArray(); MethodAttributes methodAttrs = mi.Attributes & (~MethodAttributes.Abstract); var methodBuilder = typeBuilder.DefineMethod(mi.Name, methodAttrs, CallingConventions.Standard, mi.ReturnType, parmTypes); parmInfos.Where(pi => pi.IsOut).ToList().ForEach(pi => { methodBuilder.DefineParameter(pi.Position + 1, ParameterAttributes.Out, string.Concat("arg", pi.Position)); }); //方法体 { var il = methodBuilder.GetILGenerator(); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldfld, fieldTarget); if (parmTypes.Length > 0) { for (int i = 1; i <= parmTypes.Length; ++i) { switch (i) { case 0: il.Emit(OpCodes.Ldarg_0); break; case 1: il.Emit(OpCodes.Ldarg_1); break; case 2: il.Emit(OpCodes.Ldarg_2); break; case 3: il.Emit(OpCodes.Ldarg_3); break; default: il.Emit(OpCodes.Ldarg_S, (byte)i); break; } //检查参数,如果是 CrossDomain ,并且是Action 或者是 Func<T> 进行跨域替换 if (!igoreCrossDomainAttribute) { Type prmType = parmTypes[i - 1]; var prmInfo = parmInfos[i - 1]; if (prmInfo.GetCustomAttributes(typeof(CallerDomainRun), true).Length > 0) { if (prmType.Equals(typeof(Action))) { il.Emit(OpCodes.Call, miActionConverter); } else if (prmType.IsGenericType && (prmType.BaseType == typeof(Func <>).BaseType)) { var miProxy = miFuncConverter.GetOrAdd(prmType, rt => { var typeProxy = typeof(RemoteFuncProxy <>).MakeGenericType(rt.GetGenericArguments()); return(typeProxy.GetMethod("CreateProxyFunc")); }); il.Emit(OpCodes.Call, miProxy); } } } } } il.Emit(OpCodes.Callvirt, mi); //检查返回参数类型,是不是具有序列化标志, 如果有,每次返回对象时,生成代理返回 if (mi.ReturnType != typeof(void)) { var cas = mi.ReturnType.GetCustomAttributes(typeof(DomainSerializableAttribute), true); if (cas.Length > 0) { FieldInfo fieldLoader = baseType.GetField("loader", BindingFlags.NonPublic | BindingFlags.Instance); if (fieldLoader != null) { Type loadType = typeof(RemotePluginLoader <>).MakeGenericType(mi.ReturnType); Type retWraperType = CreateSerializeableProxyType(mi.ReturnType, baseType.GetGenericTypeDefinition().MakeGenericType(targetType), true); var constructorInfo = retWraperType.GetConstructor(new[] { mi.ReturnType, loadType }); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldfld, fieldLoader); il.Emit(OpCodes.Newobj, constructorInfo); } } } //if (mi.ReturnType == typeof(void)) //{ // il.Emit(OpCodes.Pop); //} il.Emit(OpCodes.Ret); } map.Add(mi, methodBuilder); }); List <PropertyInfo> props = new List <PropertyInfo>(); props.AddRange(targetType.GetProperties()); foreach (var tt in targetType.GetInterfaces()) { props.AddRange(tt.GetProperties()); } //var props = targetType.GetProperties(); props.ToList().ForEach(pi => { var propBuilder = typeBuilder.DefineProperty(pi.Name, PropertyAttributes.HasDefault, pi.ReflectedType, null); if (pi.CanRead) { var mi = pi.GetGetMethod(); Debug.Assert(map.ContainsKey(mi)); var builder = map[mi]; propBuilder.SetGetMethod(builder); } if (pi.CanWrite) { var mi = pi.GetSetMethod(); Debug.Assert(map.ContainsKey(mi)); var builder = map[mi]; propBuilder.SetSetMethod(builder); } }); var ret = typeBuilder.CreateType(); #if EMITSAVE locker.WaitOne(5000); try { assemblyBuilder.Save(string.Concat(typeName, "_", DateTime.Now.ToString("yyyyMMddHHmmss"), Guid.NewGuid().ToString("N"), ".dll")); } catch (Exception ex) { log.Error(" assemblyBuilder.Save Error", ex); } finally { locker.ReleaseMutex(); } #endif dynamicAssembly.TryAdd(ret.Assembly.FullName, ret.Assembly); dynamicTypes.TryAdd(ret.Assembly.FullName, ret); return(ret); }
private static void GenerateAsyncTaskMethod( MethodInfo methodInfo, TypeBuilder typeBuilder) { var parameters = methodInfo .GetParameters() .ToArray(); var parameterTypes = parameters .Select(m => m.ParameterType) .ToArray(); // Task based async methods cannot have byref parameters if (parameterTypes.Any(m => m.IsByRef)) { return; } Type returnType = methodInfo.ReturnType; if (returnType == typeof(void)) { returnType = typeof(Task); } else { returnType = typeof(Task <>).MakeGenericType(returnType); } var methodBuilder = typeBuilder.DefineMethod( methodInfo.Name + "Async", MethodAttributes.Public | MethodAttributes.Final | MethodAttributes.Virtual | MethodAttributes.Abstract, returnType, parameterTypes); for (int i = 1; i <= parameterTypes.Length; i++) { methodBuilder.DefineParameter(i, ParameterAttributes.None, parameters[i - 1].Name); } var originalOperationContract = methodInfo.GetCustomAttribute <OperationContractAttribute>(); Type attrType = typeof(OperationContractAttribute); var attributeCtor = attrType .GetConstructor(Type.EmptyTypes); var actionProp = attrType.GetProperty("Action"); var replyActionProp = attrType.GetProperty("ReplyAction"); var nameProp = attrType.GetProperty("Name"); var isOneWayProp = attrType.GetProperty("IsOneWay"); var isInitiatingProp = attrType.GetProperty("IsInitiating"); var isTerminatingProp = attrType.GetProperty("IsTerminating"); string actionValue = GetOperationContractAction(methodInfo); string replyActionValue = GetOperationContractReplyAction(methodInfo); var propertyInfos = new List <PropertyInfo> { actionProp, isOneWayProp, isInitiatingProp, isTerminatingProp }; var propertyValues = new List <object> { actionValue, originalOperationContract.IsOneWay, originalOperationContract.IsInitiating, originalOperationContract.IsTerminating }; if (!originalOperationContract.IsOneWay) { propertyInfos.Add(replyActionProp); propertyValues.Add(replyActionValue); } if (!string.IsNullOrEmpty(originalOperationContract.Name)) { propertyInfos.Add(nameProp); propertyValues.Add(originalOperationContract.Name); } var attributeBuilder = new CustomAttributeBuilder( attributeCtor, new object[0], propertyInfos.ToArray(), propertyValues.ToArray()); methodBuilder.SetCustomAttribute(attributeBuilder); }
/// <summary> /// Creates an un-cached proxy class. /// </summary> /// <param name="baseType">The base <see cref="Type"/> to proxy.</param> /// <param name="properties">The collection of property names to map.</param> /// <returns> /// The proxy <see cref="Type"/>. /// </returns> private Type CreateUncachedProxyType(Type baseType, IEnumerable <string> properties) { // Create a dynamic assembly and module to store the proxy. AppDomain currentDomain = AppDomain.CurrentDomain; string typeName = $"{baseType.Name}Proxy"; string assemblyName = $"{typeName}Assembly"; string moduleName = $"{typeName}Module"; // Define different behaviors for debug and release so that we can make debugging easier. var name = new AssemblyName(assemblyName); AssemblyBuilder assemblyBuilder; #if DEBUG assemblyBuilder = currentDomain.DefineDynamicAssembly(name, AssemblyBuilderAccess.RunAndSave); ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule(moduleName, $"{moduleName}.mod", true); // Add a debuggable attribute to the assembly saying to disable optimizations Type daType = typeof(DebuggableAttribute); ConstructorInfo daCtor = daType.GetConstructor(new[] { typeof(DebuggableAttribute.DebuggingModes) }); var daBuilder = new CustomAttributeBuilder( daCtor, new object[] { DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.Default }); assemblyBuilder.SetCustomAttribute(daBuilder); #else assemblyBuilder = currentDomain.DefineDynamicAssembly(name, AssemblyBuilderAccess.Run); ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule(moduleName); #endif // Define type attributes const TypeAttributes typeAttributes = TypeAttributes.AutoClass | TypeAttributes.Class | TypeAttributes.Public | TypeAttributes.BeforeFieldInit; // Define the type. TypeBuilder typeBuilder = moduleBuilder.DefineType(typeName, typeAttributes, baseType); // Emit the default constructors for this proxy so that classes without parameterless constructors // can be proxied. ConstructorInfo[] constructors = baseType.GetConstructors(); foreach (ConstructorInfo constructorInfo in constructors) { ConstructorEmitter.Emit(typeBuilder, constructorInfo); } // Emit the IProxy IInterceptor property. FieldInfo interceptorField = InterceptorEmitter.Emit(typeBuilder); // Collect and filter our list of properties to intercept. MethodInfo[] methods = baseType.GetMethods(BindingFlags.Public | BindingFlags.Instance); IEnumerable <MethodInfo> proxyList = this.BuildPropertyList(methods) .Where(m => properties.Contains(m.Name.Substring(4), StringComparer.OrdinalIgnoreCase)); // Emit each property that is to be intercepted. foreach (MethodInfo methodInfo in proxyList) { PropertyEmitter.Emit(typeBuilder, methodInfo, interceptorField); } // Create and return. Type result = typeBuilder.CreateType(); #if DEBUG assemblyBuilder.Save(typeName + ".dll"); #endif return(result); }
// because of protobuf-net we're limited to parsing simple types at run-time as we can't parse the protobuf, but options shouldn't be too complex private void BuildExtension(string key, FieldDescriptorProto[] fields) { string name = key + "Ext" + Guid.NewGuid().ToString(); TypeBuilder extension = moduleBuilder.DefineType(name, TypeAttributes.Class); Type pcType = typeof(ProtoContractAttribute); ConstructorInfo pcCtor = pcType.GetConstructor(Type.EmptyTypes); CustomAttributeBuilder pcBuilder = new CustomAttributeBuilder(pcCtor, Type.EmptyTypes); extension.SetCustomAttribute(pcBuilder); foreach (var field in fields) { DataFormat format; bool buildEnumProxy; Type fieldType = ImageFile.LookupBasicType(field.type, out format, out buildEnumProxy); FieldBuilder fbuilder = extension.DefineField(field.name, fieldType, FieldAttributes.Public); object defaultValue = field.default_value; if (field.type == FieldDescriptorProto.Type.TYPE_ENUM) { defaultValue = 0; } else if (String.IsNullOrEmpty(field.default_value)) { if (field.type == FieldDescriptorProto.Type.TYPE_STRING) { defaultValue = ""; } else { defaultValue = Activator.CreateInstance(fieldType); } } else { try { defaultValue = Convert.ChangeType(field.default_value, fieldType); } catch (FormatException) { Console.WriteLine("Constructor for extension had bad format: {0}", key); return; } } if (buildEnumProxy) { Type epType = typeof(EnumProxyAttribute); ConstructorInfo epCtor = epType.GetConstructor(new Type[] { typeof(object), typeof(string) }); CustomAttributeBuilder epBuilder = new CustomAttributeBuilder(epCtor, new object[] { field.default_value, field.type_name }); fbuilder.SetCustomAttribute(epBuilder); } Type dvType = typeof(DefaultValueAttribute); ConstructorInfo dvCtor = dvType.GetConstructor(new Type[] { typeof(object) }); CustomAttributeBuilder dvBuilder = new CustomAttributeBuilder(dvCtor, new object[] { defaultValue }); fbuilder.SetCustomAttribute(dvBuilder); Type pmType = typeof(ProtoMemberAttribute); ConstructorInfo pmCtor = pmType.GetConstructor(new Type[] { typeof(int) }); CustomAttributeBuilder pmBuilder = new CustomAttributeBuilder(pmCtor, new object[] { field.number }, new PropertyInfo[] { pmType.GetProperty("Name"), pmType.GetProperty("DataFormat") }, new object[] { "(" + field.name + ")", format }); fbuilder.SetCustomAttribute(pmBuilder); } Type extensionType = extension.CreateType(); if (!this.protobufExtensions.ContainsKey(key)) { this.protobufExtensions[key] = new List <Type>(); } this.protobufExtensions[key].Add(extensionType); }
public Compiler(DocProject project, DocModelView[] views, DocExchangeDefinition exchange, bool psets) { this.m_project = project; this.m_views = views; this.m_exchange = exchange; this.m_psets = psets; // version needs to be included for extracting XML namespace (Major.Minor.Addendum.Corrigendum) string version = project.GetSchemaVersion(); ConstructorInfo conContract = (typeof(AssemblyVersionAttribute).GetConstructor(new Type[] { typeof(string) })); CustomAttributeBuilder cabAssemblyVersion = new CustomAttributeBuilder(conContract, new object[] { version }); string schemaid = project.GetSchemaIdentifier(); string assembly = "buildingSmart." + schemaid; string module = assembly + ".dll"; this.m_rootnamespace = assembly + "."; this.m_assembly = AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName(assembly), AssemblyBuilderAccess.RunAndSave, new CustomAttributeBuilder[] { cabAssemblyVersion }); this.m_module = this.m_assembly.DefineDynamicModule(module, module); this.m_definitions = new Dictionary <string, DocObject>(); this.m_types = new Dictionary <string, Type>(); this.m_fields = new Dictionary <Type, Dictionary <string, FieldInfo> >(); this.m_templates = new Dictionary <DocTemplateDefinition, MethodInfo>(); this.m_namespaces = new Dictionary <string, string>(); Dictionary <DocObject, bool> included = null; if (this.m_views != null) { included = new Dictionary <DocObject, bool>(); foreach (DocModelView docView in this.m_views) { this.m_project.RegisterObjectsInScope(docView, included); } } foreach (DocSection docSection in project.Sections) { foreach (DocSchema docSchema in docSection.Schemas) { foreach (DocEntity docEntity in docSchema.Entities) { if (included == null || included.ContainsKey(docEntity)) { if (!this.m_definitions.ContainsKey(docEntity.Name)) { this.m_definitions.Add(docEntity.Name, docEntity); this.m_namespaces.Add(docEntity.Name, docSchema.Name); } } } foreach (DocType docType in docSchema.Types) { if (included == null || included.ContainsKey(docType)) { if (!this.m_definitions.ContainsKey(docType.Name)) { this.m_definitions.Add(docType.Name, docType); this.m_namespaces.Add(docType.Name, docSchema.Name); } } } if (psets) { foreach (DocPropertyEnumeration docPropEnum in docSchema.PropertyEnums) { DocEnumeration docType = docPropEnum.ToEnumeration(); if (!this.m_definitions.ContainsKey(docType.Name)) { this.m_definitions.Add(docType.Name, docType); this.m_namespaces.Add(docType.Name, docSchema.Name); } } } } } // second pass: if (psets) { foreach (DocSection docSection in project.Sections) { foreach (DocSchema docSchema in docSection.Schemas) { foreach (DocPropertySet docPset in docSchema.PropertySets) { DocEntity docType = docPset.ToEntity(this.m_definitions); if (!this.m_definitions.ContainsKey(docType.Name)) { this.m_definitions.Add(docType.Name, docType); this.m_namespaces.Add(docType.Name, docSchema.Name); } } foreach (DocQuantitySet docQset in docSchema.QuantitySets) { DocEntity docType = docQset.ToEntity(this.m_definitions); if (!this.m_definitions.ContainsKey(docType.Name)) { this.m_definitions.Add(docType.Name, docType); this.m_namespaces.Add(docType.Name, docSchema.Name); } } } } } // first register types and fields foreach (string key in this.m_definitions.Keys) { Type typereg = RegisterType(key); // localization -- use custom attributes for now -- ideal way would be to use assembly resources, though has bugs in .net 4.0 if (typereg is TypeBuilder) { TypeBuilder tb = (TypeBuilder)typereg; DocObject docObj = this.m_definitions[key]; foreach (DocLocalization docLocal in docObj.Localization) { CustomAttributeBuilder cab = docLocal.ToCustomAttributeBuilder(); if (cab != null) { tb.SetCustomAttribute(cab); } } } } // now register template functions (may depend on fields existing) // find associated ConceptRoot for model view, define validation function if (this.m_views != null) { foreach (DocModelView view in this.m_views) { string viewname = view.Code; foreach (DocConceptRoot root in view.ConceptRoots) { Type tOpen = null; if (this.m_types.TryGetValue(root.ApplicableEntity.Name, out tOpen) && tOpen is TypeBuilder) { TypeBuilder tb = (TypeBuilder)tOpen; foreach (DocTemplateUsage concept in root.Concepts) { CompileConcept(concept, view, tb); } } } } } //Dictionary<string, Stream> mapResStreams = new Dictionary<string, Stream>(); //Dictionary<string, ResXResourceWriter> mapResources = new Dictionary<string, ResXResourceWriter>(); // seal types once all are built List <TypeBuilder> listBase = new List <TypeBuilder>(); foreach (string key in this.m_definitions.Keys) { Type tOpen = this.m_types[key]; while (tOpen is TypeBuilder) { listBase.Add((TypeBuilder)tOpen); tOpen = tOpen.BaseType; } // seal in base class order for (int i = listBase.Count - 1; i >= 0; i--) { Type tClosed = listBase[i].CreateType(); this.m_types[tClosed.Name] = tClosed; } listBase.Clear(); // record bindings DocDefinition docDef = this.m_definitions[key] as DocDefinition; if (docDef != null) { docDef.RuntimeType = this.m_types[key]; if (docDef is DocEntity) { DocEntity docEnt = (DocEntity)docDef; foreach (DocAttribute docAttr in docEnt.Attributes) { docAttr.RuntimeField = docDef.RuntimeType.GetField(docAttr.Name); } } #if false // bug in .net framework 4.0+ -- can't read resources dynamically defined // capture localization foreach (DocLocalization docLocal in docDef.Localization) { if (!String.IsNullOrEmpty(docLocal.Locale)) { string major = docLocal.Locale.Substring(0, 2).ToLower(); ResXResourceWriter reswriter = null; if (!mapResources.TryGetValue(major, out reswriter)) { MemoryStream stream = new MemoryStream(); mapResStreams.Add(major, stream); reswriter = new ResXResourceWriter(stream); mapResources.Add(major, reswriter); } ResXDataNode node = new ResXDataNode(docDef.Name, docLocal.Name); node.Comment = docLocal.Documentation; reswriter.AddResource(node); } } #endif } } #if false foreach (string locale in mapResStreams.Keys) { ResXResourceWriter writer = mapResources[locale]; writer.Generate(); Stream stream = mapResStreams[locale]; stream.Seek(0, SeekOrigin.Begin); m_module.DefineManifestResource("Resources." + locale + ".resx", stream, ResourceAttributes.Public); } #endif }
public void SetCustomAttribute(CustomAttributeBuilder customBuilder) { throw new PlatformNotSupportedException(); }
/// <summary> /// Creates or returns emitted type, or NULL if no such type. /// </summary> /// <param name="map"></param> /// <param name="typename"></param> /// <returns></returns> public Type RegisterType(string strtype) { // this implementation maps direct and inverse attributes to fields for brevity; a production implementation would use properties as well if (strtype == null) { return(typeof(object)); } Type type = null; // resolve standard types switch (strtype) { case "INTEGER": type = typeof(long); break; case "REAL": case "NUMBER": type = typeof(double); break; case "BOOLEAN": case "LOGICAL": type = typeof(bool); break; case "STRING": type = typeof(string); break; case "BINARY": case "BINARY (32)": type = typeof(byte[]); break; } if (type != null) { return(type); } // check for existing mapped type if (this.m_types.TryGetValue(strtype, out type)) { return(type); } // look up DocObject docType = null; if (!this.m_definitions.TryGetValue(strtype, out docType)) { return(null); } string schema = this.m_namespaces[docType.Name]; // not yet exist: create it TypeAttributes attr = TypeAttributes.Public; if (docType is DocEntity) { attr |= TypeAttributes.Class; DocEntity docEntity = (DocEntity)docType; if (docEntity.IsAbstract()) { attr |= TypeAttributes.Abstract; } Type typebase = RegisterType(docEntity.BaseDefinition); // calling base class may result in this class getting defined (IFC2x3 schema with IfcBuildingElement), so check again if (this.m_types.TryGetValue(strtype, out type)) { return(type); } TypeBuilder tb = this.m_module.DefineType(this.m_rootnamespace + schema + "." + docType.Name, attr, typebase); // add typebuilder to map temporarily in case referenced by an attribute within same class or base class this.m_types.Add(strtype, tb); // custom attributes (required for JSON serialization) ConstructorInfo conContract = (typeof(DataContractAttribute).GetConstructor(new Type[] { })); PropertyInfo propContractReference = typeof(DataContractAttribute).GetProperty("IsReference"); CustomAttributeBuilder cbContract = new CustomAttributeBuilder(conContract, new object[] { }, new PropertyInfo[] { propContractReference }, new object[] { false }); // consider setting IsReference to true if/when serializers like JSON support such referencing tb.SetCustomAttribute(cbContract); string displayname = docType.Name; if (displayname != null) { ConstructorInfo conReq = typeof(DisplayNameAttribute).GetConstructor(new Type[] { typeof(string) }); CustomAttributeBuilder cabReq = new CustomAttributeBuilder(conReq, new object[] { displayname }); tb.SetCustomAttribute(cabReq); } string description = docType.Documentation; if (description != null) { ConstructorInfo conReq = typeof(DescriptionAttribute).GetConstructor(new Type[] { typeof(string) }); CustomAttributeBuilder cabReq = new CustomAttributeBuilder(conReq, new object[] { description }); tb.SetCustomAttribute(cabReq); } // interfaces implemented by type (SELECTS) foreach (DocDefinition docdef in this.m_definitions.Values) { if (docdef is DocSelect) { DocSelect docsel = (DocSelect)docdef; foreach (DocSelectItem dsi in docsel.Selects) { if (strtype.Equals(dsi.Name)) { // register Type typeinterface = this.RegisterType(docdef.Name); tb.AddInterfaceImplementation(typeinterface); } } } } Dictionary <string, FieldInfo> mapField = new Dictionary <string, FieldInfo>(); this.m_fields.Add(tb, mapField); ConstructorInfo conMember = typeof(DataMemberAttribute).GetConstructor(new Type[] { /*typeof(int)*/ }); ConstructorInfo conInverse = typeof(InversePropertyAttribute).GetConstructor(new Type[] { typeof(string) }); PropertyInfo propMemberOrder = typeof(DataMemberAttribute).GetProperty("Order"); int order = 0; foreach (DocAttribute docAttribute in docEntity.Attributes) { DocObject docRef = null; if (docAttribute.DefinedType != null) { this.m_definitions.TryGetValue(docAttribute.DefinedType, out docRef); } // exclude derived attributes if (String.IsNullOrEmpty(docAttribute.Derived)) { Type typefield = RegisterType(docAttribute.DefinedType); if (typefield == null) { typefield = typeof(object); // excluded from scope } if (docAttribute.AggregationType != 0) { if (docAttribute.AggregationAttribute != null) { // list of list switch (docAttribute.AggregationAttribute.GetAggregation()) { case DocAggregationEnum.SET: typefield = typeof(ISet <>).MakeGenericType(new Type[] { typefield }); break; case DocAggregationEnum.LIST: default: typefield = typeof(IList <>).MakeGenericType(new Type[] { typefield }); break; } } switch (docAttribute.GetAggregation()) { case DocAggregationEnum.SET: typefield = typeof(ISet <>).MakeGenericType(new Type[] { typefield }); break; case DocAggregationEnum.LIST: default: typefield = typeof(IList <>).MakeGenericType(new Type[] { typefield }); break; } } else if (typefield.IsValueType && docAttribute.IsOptional) { typefield = typeof(Nullable <>).MakeGenericType(new Type[] { typefield }); } FieldBuilder fb = tb.DefineField("_" + docAttribute.Name, typefield, FieldAttributes.Private); mapField.Add(docAttribute.Name, fb); PropertyBuilder pb = RegisterProperty(docAttribute.Name, typefield, tb, fb); if (String.IsNullOrEmpty(docAttribute.Inverse)) { // direct attributes are fields marked for serialization CustomAttributeBuilder cb = new CustomAttributeBuilder(conMember, new object[] {}, new PropertyInfo[] { propMemberOrder }, new object[] { order }); pb.SetCustomAttribute(cb); order++; // mark if required if (!docAttribute.IsOptional) { ConstructorInfo conReq = typeof(RequiredAttribute).GetConstructor(new Type[] { }); CustomAttributeBuilder cabReq = new CustomAttributeBuilder(conReq, new object[] { }); pb.SetCustomAttribute(cabReq); } } else { // inverse attributes are fields marked for lookup CustomAttributeBuilder cb = new CustomAttributeBuilder(conInverse, new object[] { docAttribute.Inverse }); pb.SetCustomAttribute(cb); } // XML ConstructorInfo conXSD; CustomAttributeBuilder cabXSD; if (docAttribute.AggregationAttribute == null && (docRef is DocDefined || docRef is DocEnumeration)) { conXSD = typeof(XmlAttributeAttribute).GetConstructor(new Type[] { }); cabXSD = new CustomAttributeBuilder(conXSD, new object[] { }); pb.SetCustomAttribute(cabXSD); } else { switch (docAttribute.XsdFormat) { case DocXsdFormatEnum.Element: conXSD = typeof(XmlElementAttribute).GetConstructor(new Type[] { typeof(string) }); cabXSD = new CustomAttributeBuilder(conXSD, new object[] { docAttribute.DefinedType }); pb.SetCustomAttribute(cabXSD); break; case DocXsdFormatEnum.Attribute: conXSD = typeof(XmlElementAttribute).GetConstructor(new Type[] { }); cabXSD = new CustomAttributeBuilder(conXSD, new object[] { }); pb.SetCustomAttribute(cabXSD); break; case DocXsdFormatEnum.Hidden: conXSD = typeof(XmlIgnoreAttribute).GetConstructor(new Type[] { }); cabXSD = new CustomAttributeBuilder(conXSD, new object[] { }); pb.SetCustomAttribute(cabXSD); break; } } // documentation string fielddisplayname = docAttribute.Name; if (displayname != null) { ConstructorInfo conReq = typeof(DisplayNameAttribute).GetConstructor(new Type[] { typeof(string) }); CustomAttributeBuilder cabReq = new CustomAttributeBuilder(conReq, new object[] { fielddisplayname }); pb.SetCustomAttribute(cabReq); } string fielddescription = docAttribute.Documentation; if (description != null) { ConstructorInfo conReq = typeof(DescriptionAttribute).GetConstructor(new Type[] { typeof(string) }); CustomAttributeBuilder cabReq = new CustomAttributeBuilder(conReq, new object[] { fielddescription }); pb.SetCustomAttribute(cabReq); } } } // remove from typebuilder this.m_types.Remove(strtype); type = tb; // avoid circular conditions -- generate type afterwords } else if (docType is DocSelect) { attr |= TypeAttributes.Interface | TypeAttributes.Abstract; TypeBuilder tb = this.m_module.DefineType(this.m_rootnamespace + schema + "." + docType.Name, attr); // interfaces implemented by type (SELECTS) foreach (DocDefinition docdef in this.m_definitions.Values) { if (docdef is DocSelect) { DocSelect docsel = (DocSelect)docdef; foreach (DocSelectItem dsi in docsel.Selects) { if (strtype.Equals(dsi.Name)) { // register Type typeinterface = this.RegisterType(docdef.Name); tb.AddInterfaceImplementation(typeinterface); } } } } type = tb.CreateType(); } else if (docType is DocEnumeration) { DocEnumeration docEnum = (DocEnumeration)docType; EnumBuilder eb = this.m_module.DefineEnum(schema + "." + docType.Name, TypeAttributes.Public, typeof(int)); for (int i = 0; i < docEnum.Constants.Count; i++) { DocConstant docConst = docEnum.Constants[i]; FieldBuilder fb = eb.DefineLiteral(docConst.Name, (int)i); foreach (DocLocalization docLocal in docConst.Localization) { CustomAttributeBuilder cab = docLocal.ToCustomAttributeBuilder(); if (cab != null) { fb.SetCustomAttribute(cab); } } } type = eb.CreateType(); } else if (docType is DocDefined) { DocDefined docDef = (DocDefined)docType; attr |= TypeAttributes.Sealed; if (docDef.DefinedType == docDef.Name) { return(null); } TypeBuilder tb = this.m_module.DefineType(this.m_rootnamespace + schema + "." + docType.Name, attr, typeof(ValueType)); // interfaces implemented by type (SELECTS) foreach (DocDefinition docdef in this.m_definitions.Values) { if (docdef is DocSelect) { DocSelect docsel = (DocSelect)docdef; foreach (DocSelectItem dsi in docsel.Selects) { if (strtype.Equals(dsi.Name)) { // register Type typeinterface = RegisterType(docdef.Name); tb.AddInterfaceImplementation(typeinterface); } } } } Type typeliteral = RegisterType(docDef.DefinedType); if (typeliteral != null) { if (docDef.Aggregation != null && docDef.Aggregation.AggregationType != 0) { switch (docDef.Aggregation.GetAggregation()) { case DocAggregationEnum.SET: typeliteral = typeof(ISet <>).MakeGenericType(new Type[] { typeliteral }); break; case DocAggregationEnum.LIST: default: typeliteral = typeof(IList <>).MakeGenericType(new Type[] { typeliteral }); break; } } else { #if false // now use direct type -- don't recurse FieldInfo fieldval = typeliteral.GetField("Value"); while (fieldval != null) { typeliteral = fieldval.FieldType; fieldval = typeliteral.GetField("Value"); } #endif } FieldBuilder fieldValue = tb.DefineField("Value", typeliteral, FieldAttributes.Public); RegisterProperty("Value", typeliteral, tb, fieldValue); type = tb.CreateType(); Dictionary <string, FieldInfo> mapField = new Dictionary <string, FieldInfo>(); mapField.Add("Value", fieldValue); this.m_fields.Add(type, mapField); } } this.m_types.Add(strtype, type); return(type); }
public static Type AddDataContractAttributeToType(Type type) { string typeName = "Derived_" + type.Name; // create a dynamic assembly and module AssemblyName assemblyName = new AssemblyName(); assemblyName.Name = "tmpAssembly"; AssemblyBuilder assemblyBuilder = System.Threading.Thread.GetDomain().DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run); ModuleBuilder module = assemblyBuilder.DefineDynamicModule("tmpModule"); // create a new type builder TypeBuilder typeBuilder = module.DefineType(typeName, TypeAttributes.Public | TypeAttributes.Class | TypeAttributes.Class | TypeAttributes.AutoClass | TypeAttributes.AnsiClass | TypeAttributes.BeforeFieldInit | TypeAttributes.AutoLayout, null, new Type[] { typeof(IEntity) }); { DataContractAttribute dca = new DataContractAttribute(); ConstructorInfo ctor = typeof(DataContractAttribute).GetConstructor(new Type[] { }); CustomAttributeBuilder myCABuilder = new CustomAttributeBuilder(ctor, new object[] { }, new PropertyInfo[] { typeof(DataContractAttribute).GetProperty("Name") }, new object[] { typeName }); typeBuilder.SetCustomAttribute(myCABuilder); } int idx = 0; // Loop over the attributes that will be used as the properties names in out new type foreach (PropertyInfo propertyInfo in type.GetProperties()) { string propertyName = propertyInfo.Name; Type propertyType = propertyInfo.PropertyType; bool supportedType = false; if (propertyType.IsValueType) { if (propertyType.IsEnum) { propertyType = propertyType.GetEnumUnderlyingType(); } supportedType = true; } else if (propertyType == typeof(string)) { supportedType = true; } if (!supportedType) { continue; } // Generate a private field FieldBuilder field = typeBuilder.DefineField("_" + propertyName, propertyType, FieldAttributes.Private); // Generate a public property PropertyBuilder property = typeBuilder.DefineProperty(propertyName, PropertyAttributes.HasDefault, propertyType, null); // The property set and property get methods require a special set of attributes: MethodAttributes GetSetAttr = MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig; // Define the "get" accessor method for current private field. MethodBuilder currGetPropMthdBldr = typeBuilder.DefineMethod("get_" + propertyName, GetSetAttr, propertyType, Type.EmptyTypes); // Intermediate Language stuff... ILGenerator currGetIL = currGetPropMthdBldr.GetILGenerator(); currGetIL.Emit(OpCodes.Ldarg_0); currGetIL.Emit(OpCodes.Ldfld, field); currGetIL.Emit(OpCodes.Ret); // Define the "set" accessor method for current private field. MethodBuilder currSetPropMthdBldr = typeBuilder.DefineMethod("set_" + propertyName, GetSetAttr, null, new Type[] { propertyType }); // Again some Intermediate Language stuff... ILGenerator currSetIL = currSetPropMthdBldr.GetILGenerator(); currSetIL.Emit(OpCodes.Ldarg_0); currSetIL.Emit(OpCodes.Ldarg_1); currSetIL.Emit(OpCodes.Stfld, field); currSetIL.Emit(OpCodes.Ret); // Last, we must map the two methods created above to our PropertyBuilder to // their corresponding behaviors, "get" and "set" respectively. property.SetGetMethod(currGetPropMthdBldr); property.SetSetMethod(currSetPropMthdBldr); DataMemberAttribute dca = new DataMemberAttribute(); ConstructorInfo ctor = typeof(DataMemberAttribute).GetConstructor(new Type[] { }); CustomAttributeBuilder myCABuilder = new CustomAttributeBuilder(ctor, new object[] { }, new PropertyInfo[] { typeof(DataMemberAttribute).GetProperty("Name"), typeof(DataMemberAttribute).GetProperty("Order") }, new object[] { propertyName, idx }); property.SetCustomAttribute(myCABuilder); idx++; } // Generate our type Type generetedType = typeBuilder.CreateType(); return(generetedType); }
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable private static AssemblyBuilder CreateAssemblyForTypeLib(Object typeLib, String asmFileName, AssemblyName asmName, bool bPrimaryInteropAssembly, bool bReflectionOnly, bool bNoDefineVersionResource) { // Retrieve the current app domain. AppDomain currentDomain = Thread.GetDomain(); // Retrieve the directory from the assembly file name. String dir = null; if (asmFileName != null) { dir = Path.GetDirectoryName(asmFileName); if (String.IsNullOrEmpty(dir)) { dir = null; } } AssemblyBuilderAccess aba; if (bReflectionOnly) { aba = AssemblyBuilderAccess.ReflectionOnly; } else { aba = AssemblyBuilderAccess.RunAndSave; } // Create the dynamic assembly itself. AssemblyBuilder asmBldr; List <CustomAttributeBuilder> assemblyAttributes = new List <CustomAttributeBuilder>(); #if !FEATURE_CORECLR // mscorlib.dll must specify the security rules that assemblies it emits are to use, since by // default all assemblies will follow security rule set level 2, and we want to make that an // explicit decision. ConstructorInfo securityRulesCtor = typeof(SecurityRulesAttribute).GetConstructor(new Type[] { typeof(SecurityRuleSet) }); CustomAttributeBuilder securityRulesAttribute = new CustomAttributeBuilder(securityRulesCtor, new object[] { SecurityRuleSet.Level2 }); assemblyAttributes.Add(securityRulesAttribute); #endif // !FEATURE_CORECLR asmBldr = currentDomain.DefineDynamicAssembly(asmName, aba, dir, false, assemblyAttributes); // Set the Guid custom attribute on the assembly. SetGuidAttributeOnAssembly(asmBldr, typeLib); // Set the imported from COM attribute on the assembly and return it. SetImportedFromTypeLibAttrOnAssembly(asmBldr, typeLib); // Set the version information on the typelib. if (bNoDefineVersionResource) { SetTypeLibVersionAttribute(asmBldr, typeLib); } else { SetVersionInformation(asmBldr, typeLib, asmName); } // If we are generating a PIA, then set the PIA custom attribute. if (bPrimaryInteropAssembly) { SetPIAAttributeOnAssembly(asmBldr, typeLib); } return(asmBldr); }
public static Type CreateTypeFromCustomPropertys(List <CustomPropertyInfo> propertys, string assemblyName, string className) { className = className.Replace("*", ""); className = className.Replace("+", "."); var asmName = new AssemblyName() { Name = assemblyName }; ModuleBuilder moduleBuilder; if (!mModuleBuilderDic.TryGetValue(assemblyName, out moduleBuilder)) { var assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(asmName, System.Reflection.Emit.AssemblyBuilderAccess.RunAndCollect); moduleBuilder = assemblyBuilder.DefineDynamicModule(assemblyName); mModuleBuilderDic.Add(assemblyName, moduleBuilder); } var retType = moduleBuilder.GetType(className); if (retType != null) { return(retType); } var typeBuilder = moduleBuilder.DefineType(className, TypeAttributes.Class | TypeAttributes.Public, typeof(GeneratorClassBase), new Type[] { typeof(System.ComponentModel.INotifyPropertyChanged) }); // HostNode 用于与此对象所属节点通讯,修改dirty等 //public CodeGenerateSystem.Base.BaseNodeControl HostNode; var hostNodeFieldBuilder = typeBuilder.DefineField("HostNode", typeof(CodeGenerateSystem.Base.BaseNodeControl), FieldAttributes.Public); var setDirtyMethod = typeof(CodeGenerateSystem.Base.BaseNodeControl).GetMethod("set_IsDirty"); var onPropertyChangedMethod = typeof(GeneratorClassBase).GetMethod("OnPropertyChanged", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); var getSetAttr = MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName; foreach (var proInfo in propertys) { if (!IsPropertyInfoValid(proInfo)) { continue; } proInfo.CustomAction_PreDef?.Invoke(typeBuilder); var fieldBuilder = typeBuilder.DefineField("m" + proInfo.PropertyName, proInfo.PropertyType, FieldAttributes.Private); var fieldOldValueBuilder = typeBuilder.DefineField("m" + proInfo.PropertyName + "OldValue", proInfo.PropertyType, FieldAttributes.Private); // fieldBuilder.SetConstant(proInfo.CurrentValue); var proBuilder = typeBuilder.DefineProperty(proInfo.PropertyName, PropertyAttributes.HasDefault, proInfo.PropertyType, null); // proBuilder.SetConstant(proInfo.DefaultValue); bool needTypeAtt = false; if (proInfo.PropertyType == typeof(Type)) { needTypeAtt = true; } foreach (var proAtt in proInfo.PropertyAttributes) { if (proAtt is EngineNS.Editor.Editor_UseCustomEditorAttribute) { needTypeAtt = false; } if (proAtt is System.Runtime.InteropServices.OptionalAttribute) { continue; } else if (proAtt is EngineNS.Editor.Editor_BaseAttribute) { var att = proAtt as EngineNS.Editor.Editor_BaseAttribute; var consParams = att.GetConstructParams(); ConstructorInfo attConstructor; if (consParams == null) { attConstructor = proAtt.GetType().GetConstructor(Type.EmptyTypes); consParams = new object[0]; } else { Type[] paramTypes = new Type[consParams.Length]; for (int i = 0; i < consParams.Length; i++) { var consPar = consParams[i]; // consPar不应该为空,这里不判断,直接异常好抓 paramTypes[i] = consPar.GetType(); } attConstructor = proAtt.GetType().GetConstructor(paramTypes); } var attBuilder = new CustomAttributeBuilder(attConstructor, consParams); proBuilder.SetCustomAttribute(attBuilder); } else if (proAtt.GetType().FullName.Equals(typeof(EngineNS.Editor.Editor_PropertyGridDataTemplateAttribute).FullName)) { //needDataTemplateAtt = false; var att = proAtt as EngineNS.Editor.Editor_PropertyGridDataTemplateAttribute; var attConstructor = proAtt.GetType().GetConstructor(new Type[] { typeof(string), typeof(object[]) }); var attBuilder = new CustomAttributeBuilder(attConstructor, new object[] { att.DataTemplateType, att.Args }); proBuilder.SetCustomAttribute(attBuilder); } else if (proAtt is DescriptionAttribute) { var att = proAtt as DescriptionAttribute; var attConstructor = proAtt.GetType().GetConstructor(new Type[] { typeof(string) }); var attBuilder = new CustomAttributeBuilder(attConstructor, new object[] { att.Description }); proBuilder.SetCustomAttribute(attBuilder); } else if (proAtt is ReadOnlyAttribute) { var att = proAtt as ReadOnlyAttribute; var attConstructor = proAtt.GetType().GetConstructor(new Type[] { typeof(bool) }); var attBuilder = new CustomAttributeBuilder(attConstructor, new object[] { att.IsReadOnly }); proBuilder.SetCustomAttribute(attBuilder); } else if (proAtt is DisplayNameAttribute) { var att = proAtt as DisplayNameAttribute; var attConstructor = proAtt.GetType().GetConstructor(new Type[] { typeof(string) }); var attBuilder = new CustomAttributeBuilder(attConstructor, new object[] { att.DisplayName }); proBuilder.SetCustomAttribute(attBuilder); } else if (proAtt is CategoryAttribute) { var att = proAtt as CategoryAttribute; var attConstructor = proAtt.GetType().GetConstructor(new Type[] { typeof(string) }); var attBuilder = new CustomAttributeBuilder(attConstructor, new object[] { att.Category }); proBuilder.SetCustomAttribute(attBuilder); } else { bool hasZeroParamCons = false; foreach (var cons in proAtt.GetType().GetConstructors()) { var pams = cons.GetParameters(); if (pams == null || pams.Length == 0) { hasZeroParamCons = true; break; } } if (hasZeroParamCons) { var attConstructor = proAtt.GetType().GetConstructor(Type.EmptyTypes); var attBuilder = new CustomAttributeBuilder(attConstructor, new object[0]); proBuilder.SetCustomAttribute(attBuilder); } } } if (needTypeAtt) { var tempType = typeof(EngineNS.Editor.Editor_UseCustomEditorAttribute); var attConstructor = tempType.GetConstructor(new Type[0]); var attBuilder = new CustomAttributeBuilder(attConstructor, new object[0]); proBuilder.SetCustomAttribute(attBuilder); } ////// 添加DataValueAttribute特性,以便自动存取 ////var dataValueAttConstructor = typeof(CSUtility.Support.DataValueAttribute).GetConstructor(new Type[] { typeof(string), typeof(bool) }); ////var dataValueAttBuilder = new CustomAttributeBuilder(dataValueAttConstructor, new object[] { proInfo.PropertyName, true }); ////proBuilder.SetCustomAttribute(dataValueAttBuilder); // get方法 var getMethodBuilder = typeBuilder.DefineMethod(proInfo.GetMethodName, getSetAttr, proInfo.PropertyType, Type.EmptyTypes); var getIL = getMethodBuilder.GetILGenerator(); getIL.Emit(OpCodes.Ldarg_0); getIL.Emit(OpCodes.Ldfld, fieldBuilder); proInfo.CustomAction_PropertyGet?.Invoke(getIL, fieldBuilder); getIL.Emit(OpCodes.Ret); // set方法 var setMethodBuilder = typeBuilder.DefineMethod(proInfo.SetMethodName, getSetAttr, null, new Type[] { proInfo.PropertyType }); var setIL = setMethodBuilder.GetILGenerator(); var label0 = setIL.DefineLabel(); setIL.Emit(OpCodes.Ldarg_0); setIL.Emit(OpCodes.Ldarg_0); setIL.Emit(OpCodes.Ldfld, fieldBuilder); setIL.Emit(OpCodes.Stfld, fieldOldValueBuilder); setIL.Emit(OpCodes.Ldarg_0); setIL.Emit(OpCodes.Ldarg_1); setIL.Emit(OpCodes.Stfld, fieldBuilder); proInfo.CustomAction_PropertySet?.Invoke(setIL, fieldBuilder); setIL.Emit(OpCodes.Ldarg_0); setIL.Emit(OpCodes.Ldfld, hostNodeFieldBuilder); setIL.Emit(OpCodes.Brfalse_S, label0); setIL.Emit(OpCodes.Ldarg_0); setIL.Emit(OpCodes.Ldfld, hostNodeFieldBuilder); setIL.Emit(OpCodes.Ldc_I4_1); setIL.Emit(OpCodes.Callvirt, setDirtyMethod); setIL.Emit(OpCodes.Ldarg_0); setIL.Emit(OpCodes.Ldstr, proInfo.PropertyName); setIL.Emit(OpCodes.Ldarg_0); setIL.Emit(OpCodes.Ldfld, fieldBuilder); setIL.Emit(OpCodes.Box, proInfo.PropertyType); setIL.Emit(OpCodes.Ldarg_0); setIL.Emit(OpCodes.Ldfld, fieldOldValueBuilder); setIL.Emit(OpCodes.Box, proInfo.PropertyType); setIL.Emit(OpCodes.Call, onPropertyChangedMethod); setIL.MarkLabel(label0); setIL.Emit(OpCodes.Ret); proBuilder.SetGetMethod(getMethodBuilder); proBuilder.SetSetMethod(setMethodBuilder); } return(typeBuilder.CreateType()); }
internal override void Seal(TypeDescription existing = null) { if (PocoType != null || TypeBuilder != null) { return; } var name = "POCO" + Guid.NewGuid().ToString().Replace("-", ""); var protoMemberAttr = typeof(ProtoMemberAttribute).GetConstructor(new[] { typeof(int) }); var protoContractAttr = typeof(ProtoContractAttribute).GetConstructor(new Type[0]); var fields = new Dictionary <string, FieldInfo>(); TypeBuilder = ModuleBuilder.DefineType(name, TypeAttributes.Public, typeof(DynamicObject), new [] { typeof(IEnumerable) }); var ix = 1; foreach (var kv in Members.OrderBy(o => o.Key, StringComparer.Ordinal)) { var memberAttrBuilder = new CustomAttributeBuilder(protoMemberAttr, new object[] { ix }); kv.Value.Seal(existing); var propType = kv.Value.GetPocoType(existing); var field = TypeBuilder.DefineField(kv.Key, propType, FieldAttributes.Public); field.SetCustomAttribute(memberAttrBuilder); fields[kv.Key] = field; ix++; } var contractAttrBuilder = new CustomAttributeBuilder(protoContractAttr, new object[0]); TypeBuilder.SetCustomAttribute(contractAttrBuilder); // Define indexer var strEq = typeof(object).GetMethod("Equals", new[] { typeof(object) }); var tryGetIndexEmit = Sigil.Emit <TryGetIndexerDelegate> .BuildMethod(TypeBuilder, "TryGetIndex", MethodAttributes.Public | MethodAttributes.Virtual, CallingConventions.Standard | CallingConventions.HasThis); tryGetIndexEmit.LoadArgument(2); // object[] var invalid = tryGetIndexEmit.DefineLabel("invalid"); tryGetIndexEmit .Duplicate() // object[] object[] .LoadLength <object>() // int object[] .LoadConstant(1); // int int object[] tryGetIndexEmit.UnsignedBranchIfNotEqual(invalid); // object[] tryGetIndexEmit .LoadConstant(0) // int object[] .LoadElement <object>() // object .IsInstance <string>(); // int var valid = tryGetIndexEmit.DefineLabel("valid"); tryGetIndexEmit .BranchIfTrue(valid) // --empty-- .LoadArgument(2); // object[] tryGetIndexEmit.MarkLabel(invalid); tryGetIndexEmit.Pop(); // --empty-- tryGetIndexEmit .LoadArgument(3) // object& .LoadNull() // null object& .StoreIndirect(typeof(object)); // --empty-- tryGetIndexEmit .LoadConstant(0) // int .Return(); // --empty-- tryGetIndexEmit.MarkLabel(valid); tryGetIndexEmit.LoadArgument(3); // object& tryGetIndexEmit .LoadArgument(2) // object[] object& .LoadConstant(0) // int object[] object& .LoadElement <object>(); // object object& Sigil.Label next; var done = tryGetIndexEmit.DefineLabel("done"); foreach (var mem in Members) { next = tryGetIndexEmit.DefineLabel("next_" + mem.Key); var memKey = mem.Key; var field = fields[memKey]; tryGetIndexEmit .Duplicate() // object object object& .LoadConstant(memKey); // string object object object& tryGetIndexEmit.CallVirtual(strEq); // int object object7& tryGetIndexEmit.BranchIfFalse(next); // object object& tryGetIndexEmit .Pop() // object& .LoadArgument(0) // this object& .LoadField(field); // fieldType object& if (field.FieldType.IsValueType) { tryGetIndexEmit.Box(field.FieldType); // fieldType object& } tryGetIndexEmit.Branch(done); // fieldType object& tryGetIndexEmit.MarkLabel(next); // object object& } tryGetIndexEmit .Pop() // object& .LoadNull(); // null object& tryGetIndexEmit.MarkLabel(done); // *something* object& tryGetIndexEmit .StoreIndirect(typeof(object)) // --empty-- .LoadConstant(1) // int .Return(); // --empty-- var tryGetIndex = tryGetIndexEmit.CreateMethod(); TypeBuilder.DefineMethodOverride(tryGetIndex, typeof(DynamicObject).GetMethod("TryGetIndex")); // Implement IEnumerable var getEnumeratorEmit = Sigil.Emit <Func <IEnumerator> > .BuildMethod(TypeBuilder, "GetEnumerator", MethodAttributes.Public | MethodAttributes.Virtual, CallingConventions.Standard | CallingConventions.HasThis); var newStrList = typeof(List <string>).GetConstructor(new[] { typeof(int) }); var newEnumerator = Enumerator.GetConstructor(new[] { typeof(List <string>), typeof(object) }); var add = typeof(List <string>).GetMethod("Add"); getEnumeratorEmit.LoadConstant(Members.Count); getEnumeratorEmit.NewObject(newStrList); foreach (var mem in Members) { getEnumeratorEmit.Duplicate(); getEnumeratorEmit.LoadConstant(mem.Key); getEnumeratorEmit.Call(add); } getEnumeratorEmit.LoadArgument(0); getEnumeratorEmit.NewObject(newEnumerator); getEnumeratorEmit.Return(); var getEnumerator = getEnumeratorEmit.CreateMethod(); TypeBuilder.DefineMethodOverride(getEnumerator, typeof(IEnumerable).GetMethod("GetEnumerator")); // Define ToString() var toStringEmit = Sigil.Emit <Func <string> > .BuildMethod(TypeBuilder, "ToString", MethodAttributes.Public | MethodAttributes.Virtual, CallingConventions.Standard | CallingConventions.HasThis); var objToString = typeof(object).GetMethod("ToString"); var thunkField = TypeBuilder.DefineField("__ToStringThunk", typeof(Func <object, string>), FieldAttributes.Static | FieldAttributes.Private); var invoke = typeof(Func <object, string>).GetMethod("Invoke"); toStringEmit .LoadField(thunkField) .LoadArgument(0) .CallVirtual(invoke) .Return(); var toString = toStringEmit.CreateMethod(); TypeBuilder.DefineMethodOverride(toString, objToString); PocoType = TypeBuilder.CreateType(); // Set the ToStringCallback var firstInst = PocoType.GetConstructor(Type.EmptyTypes).Invoke(new object[0]); var setThunk = firstInst.GetType().GetField("__ToStringThunk", BindingFlags.NonPublic | BindingFlags.Static); setThunk.SetValue(firstInst, ToStringFunc); }
private void SetMethodImplAttribute(CustomAttributeBuilder customBuilder) { MethodImplOptions opt; switch (customBuilder.Constructor.ParameterCount) { case 0: opt = 0; break; case 1: { object val = customBuilder.GetConstructorArgument(0); if (val is short) { opt = (MethodImplOptions)(short)val; } else if (val is int) { opt = (MethodImplOptions)(int)val; } else { opt = (MethodImplOptions)val; } break; } default: throw new NotSupportedException(); } MethodCodeType? type = customBuilder.GetFieldValue<MethodCodeType>("MethodCodeType"); implFlags = (MethodImplAttributes)opt; if (type.HasValue) { implFlags |= (MethodImplAttributes)type; } }
private Type CreateFactoryType(Type tFactory, Type tInterface, Type tImplementation, string dynamicAssemblyName) { var moduleBuilder = getModuleBuilder(dynamicAssemblyName); var createMethods = tFactory.GetMethods().Where(x => x.Name == "Create").ToArray(); var factoryInterfaceType = tFactory; var singletoneAttrType = typeof(SingletoneAttribute);//created factory will be a singletone var singletonAttrCtor = singletoneAttrType.GetConstructor(new Type[0]); if (singletonAttrCtor == null) { throw new ApplicationException("Unable to find SingletoneAttribute constructor"); } var singletoneAttrBuilder = new CustomAttributeBuilder(singletonAttrCtor, new object[0]); var typeNameBase = $"{tImplementation.Name}Factory"; var typeName = typeNameBase; var idx = 0; while (_createdTypeNames.Contains(typeName))//make sure that name is unique { typeName = $"{typeNameBase}{++idx}"; } _createdTypeNames.Add(typeName); var typeBuilder = moduleBuilder.DefineType(typeName, TypeAttributes.Public | TypeAttributes.Class | TypeAttributes.AutoClass | TypeAttributes.AnsiClass | TypeAttributes.BeforeFieldInit | TypeAttributes.AutoLayout, null); typeBuilder.AddInterfaceImplementation(factoryInterfaceType); // make created factory implement interface typeBuilder.SetCustomAttribute(singletoneAttrBuilder); //add attribute var resolverField = typeBuilder.DefineField("_resolver", typeof(IResolver), FieldAttributes.Private | FieldAttributes.InitOnly); //create private field _resolver var tField = typeBuilder.DefineField("_t", typeof(Type), FieldAttributes.Private); //create private field _t of type Type var getTypeMethod = typeof(Type).GetMethod(nameof(Type.GetTypeFromHandle)) ?? throw new ApplicationException(); var resolveMethod = typeof(IResolver).GetMethod(nameof(IResolver.Resolve), new[] { typeof(Type), typeof(object[]) }); if (resolveMethod == null) { throw new ApplicationException("Unable to find Resolver.Resolve(Type, object[])"); } var ctor = typeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, new[] { typeof(IResolver) });//let's create a constructor var ctorIlGen = ctor.GetILGenerator(); //create code ctorIlGen.Emit(OpCodes.Ldarg_0); //load this on stack ctorIlGen.Emit(OpCodes.Dup); //load this on stack again ctorIlGen.Emit(OpCodes.Ldtoken, tImplementation); //load Impl type on stack ctorIlGen.Emit(OpCodes.Call, getTypeMethod); //call .GetTypeFromHandle() ctorIlGen.Emit(OpCodes.Stfld, tField); //save type value to ctorIlGen.Emit(OpCodes.Ldarg_1); //load arg1 on stack ctorIlGen.Emit(OpCodes.Stfld, resolverField); //save arg1 to field _resolver ctorIlGen.Emit(OpCodes.Ret); //return from ctor var implCtorInfos = tImplementation.GetConstructors().OrderBy(x => x.GetParameters().Length).ToList(); var usedCtorInfos = new List <ConstructorInfo>();//put used ctors here foreach (var createMethodInfo in createMethods) { var parameterTypes = createMethodInfo.GetParameters().Select(x => x.ParameterType).ToArray(); var implCtor = implCtorInfos.FirstOrDefault(x => parameterTypes.Any() && parameterTypes.All(pt => x.GetParameters().Any(cp => cp.ParameterType == pt)) || !parameterTypes.Any() && !usedCtorInfos.Contains(x)); usedCtorInfos.Add(implCtor); var createMethodImpl = typeBuilder.DefineMethod("Create", MethodAttributes.Public | MethodAttributes.Virtual, tInterface, parameterTypes); //create Create method typeBuilder.DefineMethodOverride(createMethodImpl, createMethodInfo); //override interface method (difference between abstract class in interface? ;)) var notImpEx = typeof(NotImplementedException); var notImpExCtor = notImpEx.GetConstructor( new[] { typeof(string) }); var errorMessageBuilder = new StringBuilder("Unable to find a constructor with parameters: ");//create error message if matched implementation ctor not found var ilGen = createMethodImpl.GetILGenerator(); if (parameterTypes.Length == 0) { errorMessageBuilder.Append("<no parameters>"); } var localArray = ilGen.DeclareLocal(typeof(object[])); //create local variable of type object[] (call it arr) var tmpObj = ilGen.DeclareLocal(typeof(object)); //create local variable of type object (call it obj) ilGen.Emit(OpCodes.Ldc_I4, parameterTypes.Length); //put langth value on stack ilGen.Emit(OpCodes.Newarr, typeof(object)); //create new instance of array (length will be taken from stack. see prevoius line) ilGen.Emit(OpCodes.Stloc, localArray); //save created array to arr for (var i = 0; i < parameterTypes.Length; i++) { var currentType = parameterTypes[i]; ilGen.Emit(OpCodes.Ldarg, i + 1); //load arg by index (0 skipped because arg0 = "this") ilGen.Emit(OpCodes.Stloc, tmpObj); //save loaded arg to obj ilGen.Emit(OpCodes.Ldloc, localArray); //load on stack arr ilGen.Emit(OpCodes.Ldc_I4, i); //load index on stack ilGen.Emit(OpCodes.Ldloc, tmpObj); //load obj if (currentType.IsValueType) { ilGen.Emit(OpCodes.Box, currentType);//box value typed item if necessary } else { ilGen.Emit(OpCodes.Castclass, typeof(object));//cast to object reference type } #if DEBUG ilGen.EmitWriteLine($"cur: {i} total: {parameterTypes.Length}"); //trace #endif ilGen.Emit(OpCodes.Stelem, typeof(object)); //put obj to arr at specified index (which was loaded just before obj). obj will be boxed or casted to object in process errorMessageBuilder.Append(currentType.Name); if (i < parameterTypes.Length - 1) { errorMessageBuilder.Append(", "); } } if (implCtor != null) //if implementation ctor was found { ilGen.Emit(OpCodes.Ldarg_0); //load this ilGen.Emit(OpCodes.Ldfld, resolverField); //load resolver field ilGen.Emit(OpCodes.Ldarg_0); //load this again ilGen.Emit(OpCodes.Ldfld, tField); //load _t field ilGen.Emit(OpCodes.Ldloc, localArray); //load arr ilGen.Emit(OpCodes.Call, resolveMethod); //load _resolver.Resolve(_t, arr) ilGen.Emit(OpCodes.Castclass, tImplementation); //cast returned object to Implementation type ilGen.Emit(OpCodes.Ret); //return continue; } if (notImpExCtor == null)//if exception ctor was not found (hard to imagine why it could happen) { continue; } ilGen.Emit(OpCodes.Ldstr, errorMessageBuilder.ToString()); //load error message on stack ilGen.Emit(OpCodes.Newobj, notImpExCtor); // new NotImplementedException(error message); ilGen.Emit(OpCodes.Throw); // throw created exception } return(typeBuilder.CreateTypeInfo()); }
internal static void SetMarshalAsAttribute(ModuleBuilder module, int token, CustomAttributeBuilder attribute) { attribute = attribute.DecodeBlob(module.Assembly); FieldMarshalTable.Record rec = new FieldMarshalTable.Record(); rec.Parent = token; rec.NativeType = WriteMarshallingDescriptor(module, attribute); module.FieldMarshal.AddRecord(rec); }
public void SetCustomAttribute(CustomAttributeBuilder customBuilder) { methodBuilder.SetCustomAttribute(customBuilder); }
public void SetCustomAttribute(CustomAttributeBuilder customBuilder) { this.ModuleBuilder.SetCustomAttribute((GenericParamTable.Index << 24) | paramPseudoIndex, customBuilder); }
static void BuildBeginMethods(TypeBuilder tb, ArrayList methods) { foreach (MethodData mthdData in methods) { MethodInfo mi = mthdData.mi; // assume method has already been validated for required signature int paramCount = mi.GetParameters().Length; // argCount counts of params before optional AsyncCallback param int argCount = paramCount; Type[] argTypes = new Type[paramCount]; for (int i = 0; i < mi.GetParameters().Length; i++) { argTypes[i] = mi.GetParameters()[i].ParameterType; if (argTypes[i] == typeof(System.AsyncCallback)) { argCount = i; } } MethodBuilder mthdBldr = tb.DefineMethod( mi.Name, MethodAttributes.Public | MethodAttributes.Virtual, mi.ReturnType, argTypes); // add attribute to method Type[] oneString = new Type[1] { typeof(string) }; Type methodAttr = typeof(XmlRpcBeginAttribute); ConstructorInfo ci = methodAttr.GetConstructor(oneString); CustomAttributeBuilder cab = new CustomAttributeBuilder(ci, new object[] { mthdData.xmlRpcName }); mthdBldr.SetCustomAttribute(cab); // start generating IL ILGenerator ilgen = mthdBldr.GetILGenerator(); // declare variable to store method args and emit code to populate it LocalBuilder argValues = ilgen.DeclareLocal(typeof(System.Object[])); ilgen.Emit(OpCodes.Ldc_I4, argCount); ilgen.Emit(OpCodes.Newarr, typeof(System.Object)); ilgen.Emit(OpCodes.Stloc, argValues); for (int argLoad = 0; argLoad < argCount; argLoad++) { ilgen.Emit(OpCodes.Ldloc, argValues); ilgen.Emit(OpCodes.Ldc_I4, argLoad); ilgen.Emit(OpCodes.Ldarg, argLoad + 1); ParameterInfo pi = mi.GetParameters()[argLoad]; string paramTypeName = pi.ParameterType.AssemblyQualifiedName; paramTypeName = paramTypeName.Replace("&", ""); Type paramType = Type.GetType(paramTypeName); if (paramType.IsValueType) { ilgen.Emit(OpCodes.Box, paramType); } ilgen.Emit(OpCodes.Stelem_Ref); } // emit code to store AsyncCallback parameter, defaulting to null // if not in method signature LocalBuilder acbValue = ilgen.DeclareLocal(typeof(System.AsyncCallback)); if (argCount < paramCount) { ilgen.Emit(OpCodes.Ldarg, argCount + 1); ilgen.Emit(OpCodes.Stloc, acbValue); } // emit code to store async state parameter, defaulting to null // if not in method signature LocalBuilder objValue = ilgen.DeclareLocal(typeof(System.Object)); if (argCount < (paramCount - 1)) { ilgen.Emit(OpCodes.Ldarg, argCount + 2); ilgen.Emit(OpCodes.Stloc, objValue); } // emit code to call BeginInvoke on base class Type[] invokeTypes = new Type[] { typeof(MethodInfo), typeof(object[]), typeof(System.Object), typeof(System.AsyncCallback), typeof(System.Object) }; MethodInfo invokeMethod = typeof(XmlRpcClientProtocol).GetMethod("BeginInvoke", invokeTypes); ilgen.Emit(OpCodes.Ldarg_0); ilgen.Emit(OpCodes.Call, typeof(MethodBase).GetMethod("GetCurrentMethod")); ilgen.Emit(OpCodes.Castclass, typeof(System.Reflection.MethodInfo)); ilgen.Emit(OpCodes.Ldloc, argValues); ilgen.Emit(OpCodes.Ldarg_0); ilgen.Emit(OpCodes.Ldloc, acbValue); ilgen.Emit(OpCodes.Ldloc, objValue); ilgen.Emit(OpCodes.Call, invokeMethod); // BeginInvoke will leave IAsyncResult on stack - leave it there // for return value from method being built ilgen.Emit(OpCodes.Ret); } }
public void SetCustomAttribute(CustomAttributeBuilder customBuilder) { Universe u = this.ModuleBuilder.universe; Type type = customBuilder.Constructor.DeclaringType; if (type == u.System_Runtime_InteropServices_StructLayoutAttribute) { SetStructLayoutPseudoCustomAttribute(customBuilder.DecodeBlob(this.Assembly)); } else if (type == u.System_SerializableAttribute) { attribs |= TypeAttributes.Serializable; } else if (type == u.System_Runtime_InteropServices_ComImportAttribute) { attribs |= TypeAttributes.Import; } else if (type == u.System_Runtime_CompilerServices_SpecialNameAttribute) { attribs |= TypeAttributes.SpecialName; } else { if (type == u.System_Security_SuppressUnmanagedCodeSecurityAttribute) { attribs |= TypeAttributes.HasSecurity; } this.ModuleBuilder.SetCustomAttribute(token, customBuilder); } }
/// <summary> /// create a method implementation that uses GetDelegateForFunctionPointer internally /// </summary> private static Action <object, IImportResolver> ImplementMethodDelegate(TypeBuilder type, MethodInfo baseMethod, CallingConvention nativeCall, string entryPointName, FieldInfo monitorField) { var paramInfos = baseMethod.GetParameters(); var paramTypes = paramInfos.Select(p => p.ParameterType).ToArray(); var returnType = baseMethod.ReturnType; // create the delegate type var delegateType = type.DefineNestedType("DelegateType" + baseMethod.Name, TypeAttributes.Class | TypeAttributes.NestedPrivate | TypeAttributes.Sealed, typeof(MulticastDelegate)); var delegateCtor = delegateType.DefineConstructor( MethodAttributes.RTSpecialName | MethodAttributes.HideBySig | MethodAttributes.Public, CallingConventions.Standard, new Type[] { typeof(object), typeof(IntPtr) }); delegateCtor.SetImplementationFlags(MethodImplAttributes.Runtime | MethodImplAttributes.Managed); var delegateInvoke = delegateType.DefineMethod("Invoke", MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.Virtual, returnType, paramTypes); // we have to project all of the attributes from the baseMethod to the delegateInvoke // so for something like [Out], the interop engine will see it and use it for (int i = 0; i < paramInfos.Length; i++) { var p = delegateInvoke.DefineParameter(i + 1, ParameterAttributes.None, paramInfos[i].Name); foreach (var a in paramInfos[i].GetCustomAttributes(false)) { p.SetCustomAttribute(GetAttributeBuilder(a)); } } { var p = delegateInvoke.DefineParameter(0, ParameterAttributes.Retval, baseMethod.ReturnParameter.Name); foreach (var a in baseMethod.ReturnParameter.GetCustomAttributes(false)) { p.SetCustomAttribute(GetAttributeBuilder(a)); } } delegateInvoke.SetImplementationFlags(MethodImplAttributes.Runtime | MethodImplAttributes.Managed); // add the [UnmanagedFunctionPointer] to the delegate so interop will know how to call it var attr = new CustomAttributeBuilder(typeof(UnmanagedFunctionPointerAttribute).GetConstructor(new[] { typeof(CallingConvention) }), new object[] { nativeCall }); delegateType.SetCustomAttribute(attr); // define a field on the class to hold the delegate var field = type.DefineField("DelegateField" + baseMethod.Name, delegateType, FieldAttributes.Public); var method = type.DefineMethod(baseMethod.Name, MethodAttributes.Virtual | MethodAttributes.Public, CallingConventions.HasThis, returnType, paramTypes); var il = method.GetILGenerator(); Label exc = new Label(); if (monitorField != null) // monitor: enter and then begin try { il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldfld, monitorField); il.Emit(OpCodes.Callvirt, typeof(IMonitor).GetMethod("Enter")); exc = il.BeginExceptionBlock(); } il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldfld, field); for (int i = 0; i < paramTypes.Length; i++) { il.Emit(OpCodes.Ldarg, (short)(i + 1)); } il.Emit(OpCodes.Callvirt, delegateInvoke); if (monitorField != null) // monitor: finally exit { LocalBuilder loc = null; if (returnType != typeof(void)) { loc = il.DeclareLocal(returnType); il.Emit(OpCodes.Stloc, loc); } il.Emit(OpCodes.Leave, exc); il.BeginFinallyBlock(); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldfld, monitorField); il.Emit(OpCodes.Callvirt, typeof(IMonitor).GetMethod("Exit")); il.EndExceptionBlock(); if (returnType != typeof(void)) { il.Emit(OpCodes.Ldloc, loc); } } il.Emit(OpCodes.Ret); type.DefineMethodOverride(method, baseMethod); return((o, dll) => { var entryPtr = dll.SafeResolve(entryPointName); var interopDelegate = Marshal.GetDelegateForFunctionPointer(entryPtr, delegateType.CreateType()); o.GetType().GetField(field.Name).SetValue(o, interopDelegate); }); }
public void ObjectParam_UserDefinedClass() { var cab = new CustomAttributeBuilder( typeof(C).GetConstructors()[0], new object[] { new C(1) }); }
private void SetDllImportPseudoCustomAttribute(CustomAttributeBuilder customBuilder) { CallingConvention? callingConvention = customBuilder.GetFieldValue<CallingConvention>("CallingConvention"); CharSet? charSet = customBuilder.GetFieldValue<CharSet>("CharSet"); SetDllImportPseudoCustomAttribute((string)customBuilder.GetConstructorArgument(0), (string)customBuilder.GetFieldValue("EntryPoint"), callingConvention, charSet, (bool?)customBuilder.GetFieldValue("BestFitMapping"), (bool?)customBuilder.GetFieldValue("ThrowOnUnmappableChar"), (bool?)customBuilder.GetFieldValue("SetLastError"), (bool?)customBuilder.GetFieldValue("PreserveSig"), (bool?)customBuilder.GetFieldValue("ExactSpelling")); }
/// <summary> /// Generates a method on our <see cref="TypeBuilder"/> for the specified <see cref="MethodInfo"/> /// </summary> /// <param name="tb">The <see cref="TypeBuilder"/> we're generating our type with.</param> /// <param name="mi">The <see cref="MethodInfo"/> which represents the "template" method.</param> /// <param name="dllName">The path to the DLL that we'll put in the <see cref="DllImportAttribute"/>.</param> private static void GenerateMethod(TypeBuilder tb, MethodInfo mi, string dllName) { // These are all the parameters in our method List <ParameterInfo> pis = new List <ParameterInfo>(mi.GetParameters()); // We need to keep the parameter types and attributes in a separate array. Type[] ptypes = new Type[pis.Count]; ParameterAttributes[] attrs = new ParameterAttributes[pis.Count]; for (int i = 0; i < pis.Count; i++) { ptypes[i] = pis[i].ParameterType; attrs[i] = pis[i].Attributes; } // We actually need to create TWO methods - one for the interface implementation, and one for the // P/Invoke declaration. We'll create the P/Invoke definition first. MethodBuilder smb = tb.DefineMethod( mi.Name, // The name is the same as the interface name // P/Invoke methods need special attributes... MethodAttributes.Static | MethodAttributes.Private | MethodAttributes.HideBySig, mi.ReturnType, ptypes); // Get the type of the DllImportAttribute, which we'll attach to this method Type diaType = typeof(DllImportAttribute); // Create a CustomAttributeBuilder for the DLLImportAttribute, specifying the constructor that takes a string argument. ConstructorInfo ctor = diaType.GetConstructor(new Type[] { typeof(string) }); CustomAttributeBuilder cab = new CustomAttributeBuilder(ctor, new object[] { dllName }); // Assign the DllImport attribute to the smb smb.SetCustomAttribute(cab); // Also, any attributes on the actual parameters need to be copied to the P/Invoke declaration as well. for (int i = 0; i < attrs.Length; i++) { smb.DefineParameter(i + 1, attrs[i], pis[i].Name); } // Now create the interface implementation method MethodBuilder mb = tb.DefineMethod( "IFbClient." + mi.Name, // We use the standard "Interface.Method" to do an explicit interface implementation MethodAttributes.Private | MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.Virtual | MethodAttributes.Final, mi.ReturnType, ptypes); // Also, any attributes on the actual parameters need to be copied to the P/Invoke declaration as well. for (int i = 0; i < attrs.Length; i++) { mb.DefineParameter(i + 1, attrs[i], pis[i].Name); } // We need to generate a little IL here to actually call the P/Invoke declaration. Luckily for us, since we're just // going to pass our parameters to the P/Invoke method as-is, we don't need to muck with the eval stack ;-) ILGenerator il = mb.GetILGenerator(); for (int i = 1; i <= pis.Count; i++) { EmitLdarg(il, i); } il.EmitCall(OpCodes.Call, smb, null); EmitClientInjectionToFirebirdHandleOjects(mi.ReturnType, pis, il); il.Emit(OpCodes.Ret); // Define the fact that our IFbClient.Method is the explicit interface implementation of that method tb.DefineMethodOverride(mb, mi); }
public void SetCustomAttribute(CustomAttributeBuilder customBuilder) { Universe u = this.ModuleBuilder.universe; Type type = customBuilder.Constructor.DeclaringType; if (type == u.System_Runtime_InteropServices_DllImportAttribute) { attributes |= MethodAttributes.PinvokeImpl; SetDllImportPseudoCustomAttribute(customBuilder.DecodeBlob(this.Module.Assembly)); } else if (type == u.System_Runtime_CompilerServices_MethodImplAttribute) { SetMethodImplAttribute(customBuilder.DecodeBlob(this.Module.Assembly)); } else if (type == u.System_Runtime_InteropServices_PreserveSigAttribute) { implFlags |= MethodImplAttributes.PreserveSig; } else if (type == u.System_Runtime_CompilerServices_SpecialNameAttribute) { attributes |= MethodAttributes.SpecialName; } else { if (type == u.System_Security_SuppressUnmanagedCodeSecurityAttribute) { attributes |= MethodAttributes.HasSecurity; } this.ModuleBuilder.SetCustomAttribute(pseudoToken, customBuilder); } }
/// <summary> /// 设置一个 <see cref="CustomAttributeBuilder"/> 对象。 /// </summary> /// <param name="customBuilder"></param> protected override void SetCustomAttribute(CustomAttributeBuilder customBuilder) { AssemblyBuilder.SetCustomAttribute(customBuilder); }
private static int WriteMarshallingDescriptor(ModuleBuilder module, CustomAttributeBuilder attribute) { UnmanagedType unmanagedType; object val = attribute.GetConstructorArgument(0); if (val is short) { unmanagedType = (UnmanagedType)(short)val; } else if (val is int) { unmanagedType = (UnmanagedType)(int)val; } else { unmanagedType = (UnmanagedType)val; } ByteBuffer bb = new ByteBuffer(5); bb.WriteCompressedUInt((int)unmanagedType); if (unmanagedType == UnmanagedType.LPArray) { UnmanagedType arraySubType = attribute.GetFieldValue<UnmanagedType>("ArraySubType") ?? NATIVE_TYPE_MAX; bb.WriteCompressedUInt((int)arraySubType); int? sizeParamIndex = attribute.GetFieldValue<short>("SizeParamIndex"); int? sizeConst = attribute.GetFieldValue<int>("SizeConst"); if (sizeParamIndex != null) { bb.WriteCompressedUInt(sizeParamIndex.Value); if (sizeConst != null) { bb.WriteCompressedUInt(sizeConst.Value); bb.WriteCompressedUInt(1); // flag that says that SizeParamIndex was specified } } else if (sizeConst != null) { bb.WriteCompressedUInt(0); // SizeParamIndex bb.WriteCompressedUInt(sizeConst.Value); bb.WriteCompressedUInt(0); // flag that says that SizeParamIndex was not specified } } else if (unmanagedType == UnmanagedType.SafeArray) { VarEnum? safeArraySubType = attribute.GetFieldValue<VarEnum>("SafeArraySubType"); if (safeArraySubType != null) { bb.WriteCompressedUInt((int)safeArraySubType); Type safeArrayUserDefinedSubType = (Type)attribute.GetFieldValue("SafeArrayUserDefinedSubType"); if (safeArrayUserDefinedSubType != null) { WriteType(module, bb, safeArrayUserDefinedSubType); } } } else if (unmanagedType == UnmanagedType.ByValArray) { bb.WriteCompressedUInt(attribute.GetFieldValue<int>("SizeConst") ?? 1); UnmanagedType? arraySubType = attribute.GetFieldValue<UnmanagedType>("ArraySubType"); if (arraySubType != null) { bb.WriteCompressedUInt((int)arraySubType); } } else if (unmanagedType == UnmanagedType.ByValTStr) { bb.WriteCompressedUInt(attribute.GetFieldValue<int>("SizeConst").Value); } else if (unmanagedType == UnmanagedType.Interface || unmanagedType == UnmanagedType.IDispatch || unmanagedType == UnmanagedType.IUnknown) { int? iidParameterIndex = attribute.GetFieldValue<int>("IidParameterIndex"); if (iidParameterIndex != null) { bb.WriteCompressedUInt(iidParameterIndex.Value); } } else if (unmanagedType == UnmanagedType.CustomMarshaler) { bb.WriteCompressedUInt(0); bb.WriteCompressedUInt(0); string marshalType = (string)attribute.GetFieldValue("MarshalType"); if (marshalType != null) { WriteString(bb, marshalType); } else { WriteType(module, bb, (Type)attribute.GetFieldValue("MarshalTypeRef")); } WriteString(bb, (string)attribute.GetFieldValue("MarshalCookie") ?? ""); } return module.Blobs.Add(bb); }
private void SetTypeInfo12(Type type, bool isReturnType, bool isExceptionSafe) { // isExceptionSafe determines whether or not exception wrapper will be constructed // if isExceptionSafe then no exception wrapper is created // else the wrapper function returns an object, and the XlObjectMarshaler is always // used - the wrapper then ensures that #ERROR is returned from the function // if any exception is caught. // if no exception, the return type is known to be of type BoxedReturnValueType // and unboxed accordingly. // NOTE: There is also a list of supported parameter types in // AssemblyLoader.cs, where the methods to register are extracted. // By default DelegateParamType is type // changed for some return types to ensure boxing, // to allow custom marshaling. DelegateParamType = type; if (type == typeof(double)) { if (isReturnType && !isExceptionSafe) { XlType = "Q"; // OPER12 MarshalAsAttribute = GetMarshalAsAttribute(typeof(XlObject12Marshaler)); DelegateParamType = typeof(object); BoxedValueType = typeof(double); } else { XlType = "B"; } } else if (type == typeof(string)) { // CONSIDER: Other options for string marshaling (nulls etc??) if (isReturnType) { if (!isExceptionSafe) { XlType = "Q"; // OPER MarshalAsAttribute = GetMarshalAsAttribute(typeof(XlObject12Marshaler)); DelegateParamType = typeof(object); } else { XlType = "D%"; // XlString12 MarshalAsAttribute = GetMarshalAsAttribute(typeof(XlString12ReturnMarshaler)); } } else { XlType = "C%"; // LPWSTR MarshalAsAttribute = GetMarshalAsAttribute(UnmanagedType.LPWStr); } } else if (type == typeof(DateTime)) { if (isReturnType) { if (!isExceptionSafe) { XlType = "Q"; // OPER MarshalAsAttribute = GetMarshalAsAttribute(typeof(XlObject12Marshaler)); DelegateParamType = typeof(object); BoxedValueType = typeof(DateTime); } else { // TODO: Consolidate with the above case? XlType = "E"; // double* MarshalAsAttribute = GetMarshalAsAttribute(typeof(XlDateTime12Marshaler)); DelegateParamType = typeof(object); BoxedValueType = typeof(DateTime); } } else { XlType = "E"; // double* MarshalAsAttribute = GetMarshalAsAttribute(typeof(XlDateTime12Marshaler)); DelegateParamType = typeof(object); BoxedValueType = typeof(DateTime); } } else if (type == typeof(double[])) { //if (isReturnType && !isExceptionSafe) //{ // XlType = 'P'; // OPER // MarshalAsAttribute = GetMarshalAsAttribute(typeof(XlObjectMarshaler)); // DelegateParamType = typeof(object); //} //else //{ XlType = "K%"; // FP14* MarshalAsAttribute = GetMarshalAsAttribute(typeof(XlDoubleArray12Marshaler), "1"); //} } else if (type == typeof(double[, ])) { //if (isReturnType && !isExceptionSafe) //{ // XlType = 'P'; // OPER // MarshalAsAttribute = GetMarshalAsAttribute(typeof(XlObjectMarshaler)); // DelegateParamType = typeof(object); //} //else //{ XlType = "K%"; // FP12* MarshalAsAttribute = GetMarshalAsAttribute(typeof(XlDoubleArray12Marshaler), "2"); //} } else if (type == typeof(object)) { // Before version 0.29 we had: // if (isReturnType || AllowReference) // XlType = "U"; // XLOPER // and thus registered as U in most cases. // This does not work in HPC setting, and seems to have been a mistake anyway // - returning a reference always gives #VALUE if (AllowReference) { XlType = "U"; // XLOPER } else { XlType = "Q"; // OPER } MarshalAsAttribute = GetMarshalAsAttribute(typeof(XlObject12Marshaler)); DelegateParamType = typeof(object); } else if (type == typeof(object[])) { if (isReturnType && !isExceptionSafe) { XlType = "Q"; // OPER MarshalAsAttribute = GetMarshalAsAttribute(typeof(XlObject12Marshaler)); DelegateParamType = typeof(object); } else { XlType = "Q"; // OPER MarshalAsAttribute = GetMarshalAsAttribute(typeof(XlObjectArray12Marshaler), "1"); } } else if (type == typeof(object[, ])) { if (isReturnType && !isExceptionSafe) { XlType = "Q"; // OPER MarshalAsAttribute = GetMarshalAsAttribute(typeof(XlObject12Marshaler)); DelegateParamType = typeof(object); } else { XlType = "Q"; // OPER MarshalAsAttribute = GetMarshalAsAttribute(typeof(XlObjectArray12Marshaler), "2"); } } else if (type == typeof(bool)) { if (isReturnType) { XlType = "Q"; // OPER MarshalAsAttribute = GetMarshalAsAttribute(typeof(XlObject12Marshaler)); DelegateParamType = typeof(object); BoxedValueType = typeof(bool); } else { // XlType = "J"; // int32 XlType = "Q"; // OPER MarshalAsAttribute = GetMarshalAsAttribute(typeof(XlBoolean12Marshaler)); DelegateParamType = typeof(object); BoxedValueType = typeof(bool); } } else if (type == typeof(int)) { if (isReturnType) { XlType = "Q"; // OPER MarshalAsAttribute = GetMarshalAsAttribute(typeof(XlObject12Marshaler)); DelegateParamType = typeof(object); BoxedValueType = typeof(int); } else { // XlType = "J"; XlType = "E"; // double* MarshalAsAttribute = GetMarshalAsAttribute(typeof(XlInt32Parameter12Marshaler)); DelegateParamType = typeof(object); BoxedValueType = typeof(int); } } else if (type == typeof(short)) { if (isReturnType) { XlType = "Q"; // OPER MarshalAsAttribute = GetMarshalAsAttribute(typeof(XlObject12Marshaler)); DelegateParamType = typeof(object); BoxedValueType = typeof(short); } else { // XlType = "I"; XlType = "E"; // double* MarshalAsAttribute = GetMarshalAsAttribute(typeof(XlInt16Parameter12Marshaler)); DelegateParamType = typeof(object); BoxedValueType = typeof(short); } } else if (type == typeof(ushort)) { if (isReturnType) { XlType = "Q"; // OPER MarshalAsAttribute = GetMarshalAsAttribute(typeof(XlObject12Marshaler)); DelegateParamType = typeof(object); BoxedValueType = typeof(ushort); } else { // XlType = "H"; XlType = "E"; // double* MarshalAsAttribute = GetMarshalAsAttribute(typeof(XlUInt16Parameter12Marshaler)); DelegateParamType = typeof(object); BoxedValueType = typeof(ushort); } } else if (type == typeof(decimal)) { if (isReturnType) { XlType = "Q"; // OPER MarshalAsAttribute = GetMarshalAsAttribute(typeof(XlObject12Marshaler)); DelegateParamType = typeof(object); BoxedValueType = typeof(decimal); } else { XlType = "E"; // double* MarshalAsAttribute = GetMarshalAsAttribute(typeof(XlDecimalParameter12Marshaler)); DelegateParamType = typeof(object); BoxedValueType = typeof(decimal); } } else if (type == typeof(long)) { if (isReturnType) { XlType = "Q"; // OPER MarshalAsAttribute = GetMarshalAsAttribute(typeof(XlObject12Marshaler)); DelegateParamType = typeof(object); BoxedValueType = typeof(long); } else { XlType = "E"; // double* MarshalAsAttribute = GetMarshalAsAttribute(typeof(XlInt64Parameter12Marshaler)); DelegateParamType = typeof(object); BoxedValueType = typeof(long); } } else if (type == IntegrationMarshalHelpers.ExcelAsyncHandleType && !isReturnType) { XlType = "X"; // Async Handle in XLOPER12's BigData MarshalAsAttribute = GetMarshalAsAttribute(typeof(XlAsyncHandleParameter12Marshaler)); DelegateParamType = typeof(object); } else { // The function is bad and cannot be marshaled to Excel throw new DnaMarshalException("Unknown Data Type: " + type.ToString()); } }
public void __AddDeclarativeSecurity(CustomAttributeBuilder customBuilder) { methodBuilder.__AddDeclarativeSecurity(customBuilder); }
public AssemblyGen(AssemblyName name, string outDir, string outFileExtension, bool isDebuggable) { ContractUtils.RequiresNotNull(name, "name"); #if FEATURE_FILESYSTEM if (outFileExtension == null) { outFileExtension = ".dll"; } if (outDir != null) { try { outDir = Path.GetFullPath(outDir); } catch (Exception) { throw Error.InvalidOutputDir(); } try { Path.Combine(outDir, name.Name + outFileExtension); } catch (ArgumentException) { throw Error.InvalidAsmNameOrExtension(); } _outFileName = name.Name + outFileExtension; _outDir = outDir; } // mark the assembly transparent so that it works in partial trust: CustomAttributeBuilder[] attributes = new CustomAttributeBuilder[] { new CustomAttributeBuilder(typeof(SecurityTransparentAttribute).GetConstructor(ReflectionUtils.EmptyTypes), new object[0]), #if !CLR2 && !ANDROID new CustomAttributeBuilder(typeof(SecurityRulesAttribute).GetConstructor(new[] { typeof(SecurityRuleSet) }), new object[] { SecurityRuleSet.Level1 }), #endif }; if (outDir != null) { #if !CLR2 && !ANDROID _myAssembly = AppDomain.CurrentDomain.DefineDynamicAssembly(name, AssemblyBuilderAccess.RunAndSave, outDir, false, attributes); #else //The API DefineDynamicAssembly is obsolete in Dev10. _myAssembly = AppDomain.CurrentDomain.DefineDynamicAssembly(name, AssemblyBuilderAccess.RunAndSave, outDir, null, null, null, null, false, attributes); #endif _myModule = _myAssembly.DefineDynamicModule(name.Name, _outFileName, isDebuggable); } else { _myAssembly = AppDomain.CurrentDomain.DefineDynamicAssembly(name, AssemblyBuilderAccess.Run, attributes); _myModule = _myAssembly.DefineDynamicModule(name.Name, isDebuggable); } _myAssembly.DefineVersionInfoResource(); #else _myAssembly = ReflectionUtils.DefineDynamicAssembly(name, AssemblyBuilderAccess.Run); _myModule = _myAssembly.DefineDynamicModule(name.Name, isDebuggable); #endif _isDebuggable = isDebuggable; if (isDebuggable) { SetDebuggableAttributes(); } }
private void SetStructLayoutPseudoCustomAttribute(CustomAttributeBuilder customBuilder) { object val = customBuilder.GetConstructorArgument(0); LayoutKind layout; if (val is short) { layout = (LayoutKind)(short)val; } else { layout = (LayoutKind)val; } StructLayoutAttribute attr = new StructLayoutAttribute(layout); attr.Pack = (int?)customBuilder.GetFieldValue("Pack") ?? 0; attr.Size = (int?)customBuilder.GetFieldValue("Size") ?? 0; attr.CharSet = customBuilder.GetFieldValue<CharSet>("CharSet") ?? CharSet.None; attribs &= ~TypeAttributes.LayoutMask; switch (attr.Value) { case LayoutKind.Auto: attribs |= TypeAttributes.AutoLayout; break; case LayoutKind.Explicit: attribs |= TypeAttributes.ExplicitLayout; break; case LayoutKind.Sequential: attribs |= TypeAttributes.SequentialLayout; break; } attribs &= ~TypeAttributes.StringFormatMask; switch (attr.CharSet) { case CharSet.None: case CharSet.Ansi: attribs |= TypeAttributes.AnsiClass; break; case CharSet.Auto: attribs |= TypeAttributes.AutoClass; break; case CharSet.Unicode: attribs |= TypeAttributes.UnicodeClass; break; } pack = (short)attr.Pack; size = attr.Size; hasLayout = pack != 0 || size != 0; }
private static Type CreateSurrogateType(HashSet <Type> knownExposedTypes, Type type) { CustomAttributeBuilder dataContractAttBuilder = DataContractSurrogateGenerator.GetDataContractAttributeBuilder(type); // Emit a dynamic type. TypeAttributes typeAttributes = TypeAttributes.Public; if (type.IsSealed) { typeAttributes |= TypeAttributes.Sealed; } TypeBuilder typeBuilder = DataContractSurrogateGenerator.moduleBuilder.DefineType(type.FullName, typeAttributes); if (dataContractAttBuilder != null) { typeBuilder.SetCustomAttribute(dataContractAttBuilder); } // Attach a [SecuritySafeCritical] to the surrogate type to permit its setters to deal with // types that may be SafeCritical or Critical // If the AppDomain is running in medium trust, this attribute won't have any effect. CustomAttributeBuilder safeCriticalAttrBuilder = new CustomAttributeBuilder( typeof(SecuritySafeCriticalAttribute).GetConstructor(Type.EmptyTypes), Array.Empty <object>()); typeBuilder.SetCustomAttribute(safeCriticalAttrBuilder); Type actualParentType; Type parentSurrogateType = DataContractSurrogateGenerator.GetSurrogateType(knownExposedTypes, type.BaseType); if (parentSurrogateType != null) { // Figure out what the actual parent of the exposed type is. actualParentType = type.BaseType; while (actualParentType != typeof(object)) { if (knownExposedTypes.Contains(actualParentType)) { break; } actualParentType = actualParentType.BaseType; } typeBuilder.SetParent(parentSurrogateType); } else { parentSurrogateType = typeof(object); actualParentType = typeof(object); } FieldInfo wrapperField = EmitICloneableImplementation(typeBuilder, type, parentSurrogateType); EmitConstructorsAndProperties(typeBuilder, type, parentSurrogateType, actualParentType, wrapperField); EmitOnDeserializingMethod(typeBuilder, type, wrapperField); EmitContractNamespaceAttributes(type); return(typeBuilder.CreateType()); }
public void __AddDeclarativeSecurity(CustomAttributeBuilder customBuilder) { attribs |= TypeAttributes.HasSecurity; if (declarativeSecurity == null) { declarativeSecurity = new List<CustomAttributeBuilder>(); } declarativeSecurity.Add(customBuilder); }
// Emit a surrogate property for a virtual property (a property that doesn't exist on the physical CLR type). // The PropertyDescriptor for each virtual property is initialized in the type initializer of a surrogate type. // The surrogate code we'll generate will look like this: // public <PropertyType> <PropertyName> { // get { // // For reference types. // return (<PropertyType>)$<PropertyName>.GetValue(_$wrapper); // // // For value types. // object value = $<PropertyName>.GetValue(_$wrapper); // if (value == null) { // return default(value); // } // return (<PropertyType>)value; // // // For Binary. // Binary value = (Binary)$<PropertyName>.GetValue(_$wrapper); // if (value == null) { // return null; // } // return value.ToArray(); // } // set { // if (value == null) { // return; // } // // // For normal types. // $<PropertyName>.SetValue(_$wrapper, value); // // // For value types. // $<PropertyName>.SetValue(_$wrapper, (object)value); // // // For Binary. // Binary valueToStore; // if (value == null) { // valueToStore = null; // } // else { // valueToStore = new Binary(value); // } // $<PropertyName>.SetValue(_$wrapper, valueToStore); // } // } private static void EmitAttachedProperty(TypeBuilder typeBuilder, FieldInfo wrapperField, Lazy <ILGenerator> typeInitializerFactory, PropertyDescriptor pd, string name) { // private static PropertyDescriptor $property; FieldBuilder propertyDescFieldBuilder = typeBuilder.DefineField("$" + name, typeof(PropertyDescriptor), FieldAttributes.Private | FieldAttributes.Static); EmitPropertyInitializer(propertyDescFieldBuilder, typeInitializerFactory, name); Type propertyType = SerializationUtility.GetClientType(pd.PropertyType); PropertyBuilder propertyBuilder = typeBuilder.DefineProperty(name, PropertyAttributes.None, propertyType, null); CustomAttributeBuilder dataMemberAtt = DataContractSurrogateGenerator.GetDataMemberAttributeBuilder( pd.Attributes[typeof(DataMemberAttribute)] as DataMemberAttribute); propertyBuilder.SetCustomAttribute(dataMemberAtt); // get { // return $property.GetValue(_$wrapper); // } MethodBuilder getPropertyMethodBuilder = typeBuilder.DefineMethod("get_" + name, MethodAttributes.Public, propertyType, Type.EmptyTypes); ILGenerator generator = getPropertyMethodBuilder.GetILGenerator(); // Get the PropertyDescriptor. generator.Emit(OpCodes.Ldsfld, propertyDescFieldBuilder); // Push the wrapper object onto the stack. We'll use it as an argument for our // call to GetValue later on. generator.Emit(OpCodes.Ldarg_0); generator.Emit(OpCodes.Ldfld, wrapperField); // PropertyDescriptor.GetValue(_$wrapper). generator.Emit(OpCodes.Callvirt, typeof(PropertyDescriptor).GetMethod("GetValue")); // Unbox/cast. DynamicMethodUtility.EmitFromObjectConversion(generator, pd.PropertyType); // Deal with client-server type conversions. if (propertyType != pd.PropertyType) { EmitToClientConversion(generator, pd.PropertyType, propertyType); } generator.Emit(OpCodes.Ret); propertyBuilder.SetGetMethod(getPropertyMethodBuilder); MethodBuilder setPropertyMethodBuilder = typeBuilder.DefineMethod("set_" + name, MethodAttributes.Public, null, new Type[] { propertyType }); generator = setPropertyMethodBuilder.GetILGenerator(); Label returnLabel = generator.DefineLabel(); // Data members require a getter and setter. However, if the real property is read-only, make sure // our surrogate property setter is a no-op. if (!pd.IsReadOnly) { // NOTE: We don't ever set null values, because a property may be required. For // original objects however it's possible that required properties are not // roundtripped, as they may not have RoundtripOriginalAttribute. // set { // if (value != null) { // $property.SetValue(_$wrapper, value); // } // } // If the value is null, return. if (!propertyType.IsValueType) { generator.Emit(OpCodes.Ldarg_1); EmitBranchIfNull(generator, propertyType, returnLabel); } else if (TypeUtility.IsNullableType(propertyType)) { generator.Emit(OpCodes.Ldarga_S, 1); EmitBranchIfNull(generator, propertyType, returnLabel); } // Get the PropertyDescriptor. generator.Emit(OpCodes.Ldsfld, propertyDescFieldBuilder); // Push the wrapper object onto the stack. We'll use it as an argument for our // call to SetValue later on. generator.Emit(OpCodes.Ldarg_0); generator.Emit(OpCodes.Ldfld, wrapperField); // Push the value onto the stack. We'll use it as the 2nd argument for // our call to SetValue. generator.Emit(OpCodes.Ldarg_1); // Deal with client-server type conversions. if (propertyType != pd.PropertyType) { EmitToServerConversion(generator, propertyType, pd.PropertyType); } // Box value types. DynamicMethodUtility.EmitToObjectConversion(generator, pd.PropertyType); // PropertyDescriptor.SetValue(_$wrapper, value). generator.Emit(OpCodes.Callvirt, typeof(PropertyDescriptor).GetMethod("SetValue")); } generator.MarkLabel(returnLabel); generator.Emit(OpCodes.Ret); propertyBuilder.SetSetMethod(setPropertyMethodBuilder); }