/// <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()); }
/// <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); } } }
/// <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()); }