/// <inheritdoc />
        public override TypeInfo Generate()
        {
            var argType   = _invokeDelegateField.FieldType;
            var proxyCtor = DynamicTypeBuilder.DefineConstructor(
                MethodAttributes.Public, CallingConventions.HasThis, new [] { argType });

            var badeType    = DynamicTypeBuilder.BaseType.GetTypeInfo();
            var baseCtor    = badeType.DeclaredConstructors.Single(c => c.IsPublic && c.GetParameters().Length == 0);
            var ilGenerator = proxyCtor.GetILGenerator();

            ilGenerator.Emit(OpCodes.Ldarg_0);
            ilGenerator.Emit(OpCodes.Call, baseCtor);
            ilGenerator.Emit(OpCodes.Ldarg_0);
            ilGenerator.Emit(OpCodes.Ldarg_1);
            ilGenerator.Emit(OpCodes.Stfld, _invokeDelegateField);
            ilGenerator.Emit(OpCodes.Ret);

            return(DynamicTypeBuilder.CreateTypeInfo());
        }
Beispiel #2
0
        /// <summary>
        /// 定义构造器重载。
        /// </summary>
        /// <param name="globalIntercepts"></param>
        /// <param name="builder"></param>
        private static void DefineConstructors(DynamicTypeBuilder builder, IList <InterceptAttribute> globalIntercepts)
        {
            var constructors = builder.BaseType.GetConstructors(BindingFlags.Public | BindingFlags.Instance);

            foreach (var conInfo in constructors)
            {
                var parameters = conInfo.GetParameters();

                //定义构造函数,在方法体内调用父类的同一方法
                //如 base.dosomething(a, b, c);
                var cb = builder.DefineConstructor(parameters.Select(s => s.ParameterType).ToArray(), ilCoding:
                                                   bc => bc.Emitter.ldarg_0.For(0, parameters.Length, (e, i) => e.ldarg(i + 1)).call(conInfo).ret()
                                                   );

                //定义参数
                foreach (var par in parameters)
                {
                    cb.DefineParameter(par.Name, par.DefaultValue != DBNull.Value, par.DefaultValue);
                }
            }
        }
Beispiel #3
0
        /// <inheritdoc />
        public override TypeInfo Generate()
        {
            // Create backing field as:
            // private string assemblyName;
            var assemblyNameField =
                DynamicTypeBuilder.DefineField("assemblyName", typeof(string), FieldAttributes.Private);

            // Create ctor as:
            // public IgnoresAccessChecksToAttribute(string)
            var constructorBuilder = DynamicTypeBuilder.DefineConstructor(MethodAttributes.Public,
                                                                          CallingConventions.HasThis,
                                                                          new[] { assemblyNameField.FieldType });

            var il = constructorBuilder.GetILGenerator();

            // Create ctor body as:
            // this.assemblyName = {ctor parameter 0}
            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Ldarg, 1);
            il.Emit(OpCodes.Stfld, assemblyNameField);

            // return
            il.Emit(OpCodes.Ret);

            // Define property as:
            // public string AssemblyName {get { return this.assemblyName; } }

            // ReSharper disable once UnusedVariable
            var getterPropertyBuilder = DynamicTypeBuilder.DefineProperty(
                "AssemblyName",
                PropertyAttributes.None,
                CallingConventions.HasThis,
                returnType: typeof(string),
                parameterTypes: null);

            var getterMethodBuilder = DynamicTypeBuilder.DefineMethod(
                "get_AssemblyName",
                MethodAttributes.Public,
                CallingConventions.HasThis,
                returnType: typeof(string),
                parameterTypes: null);

            // Generate body:
            // return this.assemblyName;
            il = getterMethodBuilder.GetILGenerator();
            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Ldfld, assemblyNameField);
            il.Emit(OpCodes.Ret);

            // Generate the AttributeUsage attribute for this attribute type:
            // [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
            var attributeUsageTypeInfo = typeof(AttributeUsageAttribute).GetTypeInfo();

            // Find the ctor that takes only AttributeTargets
            var attributeUsageConstructorInfo =
                attributeUsageTypeInfo.DeclaredConstructors
                .Single(c => c.GetParameters().Length == 1 &&
                        c.GetParameters()[0].ParameterType == typeof(AttributeTargets));

            // Find the property to set AllowMultiple
            var allowMultipleProperty =
                attributeUsageTypeInfo.DeclaredProperties
                .Single(f => string.Equals(f.Name, "AllowMultiple"));

            // Create a builder to construct the instance via the ctor and property
            var customAttributeBuilder =
                new CustomAttributeBuilder(attributeUsageConstructorInfo,
                                           new object[] { AttributeTargets.Assembly },
                                           new[] { allowMultipleProperty },
                                           new object[] { true });

            // Attach this attribute instance to the newly defined attribute type
            DynamicTypeBuilder.SetCustomAttribute(customAttributeBuilder);

            // Make the TypeInfo real so the constructor can be used.
            return(DynamicTypeBuilder.CreateTypeInfo());
        }