예제 #1
0
        internal static IProducer AddToModule(ModuleBuilder module, ConstructorInfo ctor)
        {
            if (ctor.DeclaringType.IsValueType)
            {
                throw new ArgumentException("Cannot emit Constructors of value-types (yet): " +
                                            (object)ctor.DeclaringType);
            }
            Type        declaringType = ctor.DeclaringType;
            string      str           = AccessorMgr.NextTypeName(ctor.GetFullMemberName());
            TypeBuilder typeBuilder   = module.DefineType(str, TypeAttributes.Public);

            typeBuilder.AddInterfaceImplementation(typeof(IProducer));
            Type[]      parameterTypes = new Type[0];
            Type        returnType     = typeof(object);
            ILGenerator ilGenerator    = typeBuilder.DefineMethod("Produce",
                                                                  MethodAttributes.Public | MethodAttributes.Virtual, returnType, parameterTypes).GetILGenerator();

            ilGenerator.DeclareLocal(declaringType);
            ilGenerator.Emit(OpCodes.Newobj, ctor);
            ilGenerator.Emit(OpCodes.Stloc_0);
            ilGenerator.Emit(OpCodes.Ldloc_0);
            ilGenerator.Emit(OpCodes.Ret);
            typeBuilder.CreateType();
            IProducer instance = module.Assembly.CreateInstance(str) as IProducer;

            if (instance == null)
            {
                throw new Exception("Unable to create producer.");
            }
            return(instance);
        }
예제 #2
0
        public static IGetterSetter AddToModule(ModuleBuilder module, FieldInfo field)
        {
            string      str           = AccessorMgr.NextTypeName(field.GetFullMemberName());
            Type        declaringType = field.DeclaringType;
            Type        fieldType     = field.FieldType;
            TypeBuilder typeBuilder   = module.DefineType(str, TypeAttributes.Public);

            typeBuilder.AddInterfaceImplementation(typeof(IGetterSetter));
            Type[] parameterTypes1 = new Type[1]
            {
                typeof(object)
            };
            Type        returnType   = typeof(object);
            ILGenerator ilGenerator1 = typeBuilder.DefineMethod("Get",
                                                                MethodAttributes.Public | MethodAttributes.Virtual, returnType, parameterTypes1).GetILGenerator();

            ilGenerator1.DeclareLocal(typeof(object));
            ilGenerator1.Emit(OpCodes.Ldarg_1);
            ilGenerator1.Emit(OpCodes.Castclass, declaringType);
            ilGenerator1.Emit(OpCodes.Ldfld, field);
            if (fieldType.IsValueType)
            {
                ilGenerator1.Emit(OpCodes.Box, fieldType);
            }
            ilGenerator1.Emit(OpCodes.Stloc_0);
            ilGenerator1.Emit(OpCodes.Ldloc_0);
            ilGenerator1.Emit(OpCodes.Ret);
            Type[] parameterTypes2 = new Type[2]
            {
                typeof(object),
                typeof(object)
            };
            ILGenerator ilGenerator2 = typeBuilder.DefineMethod("Set",
                                                                MethodAttributes.Public | MethodAttributes.Virtual, (Type)null, parameterTypes2).GetILGenerator();

            ilGenerator2.DeclareLocal(fieldType);
            ilGenerator2.Emit(OpCodes.Ldarg_1);
            ilGenerator2.Emit(OpCodes.Castclass, declaringType);
            ilGenerator2.Emit(OpCodes.Ldarg_2);
            if (fieldType.IsValueType)
            {
                ilGenerator2.Emit(OpCodes.Unbox_Any, fieldType);
            }
            ilGenerator2.Emit(OpCodes.Stfld, field);
            ilGenerator2.Emit(OpCodes.Ret);
            typeBuilder.CreateType();
            IGetterSetter instance = module.Assembly.CreateInstance(str) as IGetterSetter;

            if (instance == null)
            {
                throw new Exception("Unable to create Field accessor.");
            }
            return(instance);
        }
예제 #3
0
        public static IGetterSetter AddToModule(ModuleBuilder module, PropertyInfo prop)
        {
            string      str           = AccessorMgr.NextTypeName(prop.GetFullMemberName());
            Type        declaringType = prop.DeclaringType;
            TypeBuilder typeBuilder   = module.DefineType(str, TypeAttributes.Public);

            typeBuilder.AddInterfaceImplementation(typeof(IGetterSetter));
            Type[] parameterTypes1 = new Type[1]
            {
                typeof(object)
            };
            Type        returnType1  = typeof(object);
            ILGenerator ilGenerator1 = typeBuilder.DefineMethod("Get",
                                                                MethodAttributes.Public | MethodAttributes.Virtual, returnType1, parameterTypes1).GetILGenerator();
            MethodInfo getMethod = prop.GetGetMethod();

            if (getMethod != (MethodInfo)null)
            {
                ilGenerator1.DeclareLocal(typeof(object));
                ilGenerator1.Emit(OpCodes.Ldarg_1);
                ilGenerator1.Emit(OpCodes.Castclass, declaringType);
                ilGenerator1.EmitCall(OpCodes.Call, getMethod, (Type[])null);
                if (getMethod.ReturnType.IsValueType)
                {
                    ilGenerator1.Emit(OpCodes.Box, getMethod.ReturnType);
                }
                ilGenerator1.Emit(OpCodes.Stloc_0);
                ilGenerator1.Emit(OpCodes.Ldloc_0);
            }
            else
            {
                ilGenerator1.ThrowException(typeof(MissingMethodException));
            }

            ilGenerator1.Emit(OpCodes.Ret);
            Type[] parameterTypes2 = new Type[2]
            {
                typeof(object),
                typeof(object)
            };
            Type        returnType2  = (Type)null;
            ILGenerator ilGenerator2 = typeBuilder.DefineMethod("Set",
                                                                MethodAttributes.Public | MethodAttributes.Virtual, returnType2, parameterTypes2).GetILGenerator();
            MethodInfo setMethod = prop.GetSetMethod();

            if (setMethod != (MethodInfo)null)
            {
                Type parameterType = setMethod.GetParameters()[0].ParameterType;
                ilGenerator2.DeclareLocal(parameterType);
                ilGenerator2.Emit(OpCodes.Ldarg_1);
                ilGenerator2.Emit(OpCodes.Castclass, declaringType);
                ilGenerator2.Emit(OpCodes.Ldarg_2);
                if (parameterType.IsValueType)
                {
                    ilGenerator2.Emit(OpCodes.Unbox, parameterType);
                    OpCode opcode;
                    if (AccessorMgr.PropTypesHashes.TryGetValue(parameterType, out opcode))
                    {
                        ilGenerator2.Emit(opcode);
                    }
                    else
                    {
                        ilGenerator2.Emit(OpCodes.Ldobj, parameterType);
                    }
                }
                else
                {
                    ilGenerator2.Emit(OpCodes.Castclass, parameterType);
                }

                ilGenerator2.EmitCall(OpCodes.Callvirt, setMethod, (Type[])null);
            }
            else
            {
                ilGenerator2.ThrowException(typeof(MissingMethodException));
            }

            ilGenerator2.Emit(OpCodes.Ret);
            typeBuilder.CreateType();
            IGetterSetter instance = module.Assembly.CreateInstance(str) as IGetterSetter;

            if (instance == null)
            {
                throw new Exception("Unable to create property accessor for \"" + (object)prop + "\" of type: " +
                                    prop.DeclaringType.FullName);
            }
            return(instance);
        }