protected override void Implement(DynamicTypeBuilder config, TypeBuilder typeBuilder, ILGenerator il) { var prop = typeof(DynamicObjectBase).GetProperty("DelegateRegister", BindingFlags.NonPublic | BindingFlags.Instance); var getEnumerator = typeof(IEnumerable <Delegate>).GetMethod("GetEnumerator"); var moveNext = typeof(IEnumerator).GetMethod("MoveNext"); var getCurrent = typeof(IEnumerator <Delegate>).GetProperty("Current").GetGetMethod(); var getoraddMethod = typeof(ConcurrentDictionary <string, List <Delegate> >).GetMethod("GetOrAdd", new[] { typeof(string), typeof(List <Delegate>) }); var subscribed = il.DeclareLocal(typeof(List <Delegate>)); var enumerator = il.DeclareLocal(typeof(IEnumerator <Delegate>)); il.Emit(OpCodes.Ldarg_0); il.EmitCall(OpCodes.Callvirt, prop.GetGetMethod(true), null); il.Emit(OpCodes.Ldstr, this.MemberName); il.Emit(OpCodes.Newobj, typeof(List <Delegate>).GetConstructor(new Type[] { })); il.EmitCall(OpCodes.Callvirt, getoraddMethod, null); il.Emit(OpCodes.Stloc_S, subscribed); il.Emit(OpCodes.Ldloc_S, subscribed); il.EmitCall(OpCodes.Callvirt, getEnumerator, null); il.Emit(OpCodes.Stloc_S, enumerator); var exitLabel = il.DefineLabel(); var loopStart = il.DefineLabel(); il.MarkLabel(loopStart); il.Emit(OpCodes.Ldloc_S, enumerator); il.EmitCall(OpCodes.Callvirt, moveNext, null); il.Emit(OpCodes.Brfalse, exitLabel); var arg = this.ArgumentTypes.FirstOrDefault(); var actionType = typeof(Action); if (arg != null) { actionType = typeof(Action <>).MakeGenericType(arg); } il.Emit(OpCodes.Ldloc_S, enumerator); il.EmitCall(OpCodes.Callvirt, getCurrent, null); il.Emit(OpCodes.Castclass, actionType); if (arg != null) { il.Emit(OpCodes.Ldarg_1); } il.EmitCall(OpCodes.Callvirt, actionType.GetMethod("Invoke"), null); il.Emit(OpCodes.Br_S, loopStart); il.MarkLabel(exitLabel); il.Emit(OpCodes.Ret); }
public override void Implement(DynamicTypeBuilder config, TypeBuilder typeBuilder) { var addMethodIL = AddMethod.GetILGenerator(); GenerateHandlerMethods(BackingField, addMethodIL, true); var removeMethodIL = RemoveMethod.GetILGenerator(); GenerateHandlerMethods(BackingField, removeMethodIL, false); }
public override void Implement(DynamicTypeBuilder config, System.Reflection.Emit.TypeBuilder typeBuilder) { var il = this.AddMethod.GetILGenerator(); ProxyMethodHelper.GenerateBody(il, this._implementation.PropertyGetMethod, this._baseEvent.GetAddMethod()); var il2 = this.RemoveMethod.GetILGenerator(); ProxyMethodHelper.GenerateBody(il2, this._implementation.PropertyGetMethod, this._baseEvent.GetRemoveMethod()); }
public override void Implement(DynamicTypeBuilder config, System.Reflection.Emit.TypeBuilder typeBuilder) { var il = this.PropertyGetMethod.GetILGenerator(); ProxyMethodHelper.GenerateBody(il, this._implementation.PropertyGetMethod, this._baseProperty.GetGetMethod()); if (!this.IsReadOnly) { var il2 = this.PropertySetMethod.GetILGenerator(); ProxyMethodHelper.GenerateBody(il2, this._implementation.PropertyGetMethod, this._baseProperty.GetSetMethod()); } }
public override void Implement(DynamicTypeBuilder config, TypeBuilder typeBuilder) { // GET method il var baseProperty = typeBuilder.BaseType.GetProperty(this.MemberName); var getMethodIlGenerator = PropertyGetMethod.GetILGenerator(); if (HasBase) { getMethodIlGenerator.Emit(OpCodes.Ldarg_0); getMethodIlGenerator.Emit(OpCodes.Call, baseProperty.GetGetMethod()); getMethodIlGenerator.Emit(OpCodes.Ret); } else { getMethodIlGenerator.Emit(OpCodes.Ldarg_0); getMethodIlGenerator.Emit(OpCodes.Ldfld, this.BackingField); getMethodIlGenerator.Emit(OpCodes.Ret); } // SET method il if (!IsReadOnly) { var setMethodIlGenerator = PropertySetMethod.GetILGenerator(); Label returnLabel; Label originalReturn = returnLabel = setMethodIlGenerator.DefineLabel(); foreach (var interceptor in this.SetInterceptors) { interceptor.Intercept(this, PropertySetMethod, setMethodIlGenerator, ref returnLabel); } if (HasBase) { setMethodIlGenerator.Emit(OpCodes.Ldarg_0); setMethodIlGenerator.Emit(OpCodes.Ldarg_1); setMethodIlGenerator.Emit(OpCodes.Call, baseProperty.GetSetMethod()); } else { setMethodIlGenerator.Emit(OpCodes.Ldarg_0); setMethodIlGenerator.Emit(OpCodes.Ldarg_1); setMethodIlGenerator.Emit(OpCodes.Stfld, BackingField); } setMethodIlGenerator.Emit(OpCodes.Br_S, returnLabel); setMethodIlGenerator.MarkLabel(originalReturn); setMethodIlGenerator.Emit(OpCodes.Ret); } }
public abstract void Implement(DynamicTypeBuilder config, TypeBuilder typeBuilder);
public override void Implement(DynamicTypeBuilder config, System.Reflection.Emit.TypeBuilder typeBuilder) { }
protected abstract void Implement(DynamicTypeBuilder config, TypeBuilder typeBuilder, ILGenerator il);
public override sealed void Implement(DynamicTypeBuilder config, TypeBuilder typeBuilder) { Implement(config, typeBuilder, ImplementationMethod.GetILGenerator()); var il = this.Method.GetILGenerator(); var parameterArrayVar = il.DeclareLocal(typeof(object[])); bool isAsync = false; if (this.MemberType != null && typeof(Task).IsAssignableFrom(TypeLookup(this.MemberType))) { isAsync = true; } var ctxType = isAsync ? typeof(AsyncInterceptionContext) : typeof(InterceptionContext); var ctxVar = il.DeclareLocal(ctxType); var interceptionContextCtor = ctxType.GetConstructors().First(); ConstructorInfo delegateCtor = null; if (this.MemberType == null) { Assembly assembly = null; if (this.ArgumentTypes.Count < 9) { assembly = typeof(Action).GetTypeInfo().Assembly; } else { assembly = typeof(Enumerable).GetTypeInfo().Assembly; } var type = GetActionType(this._argumentTypes.Count); delegateCtor = type.GetConstructor(new[] { typeof(object), typeof(IntPtr) }); if (_argumentTypes.Count > 0) { type = type.MakeGenericType(TypeLookup(this.ArgumentTypes).ToArray()); } if (this._argumentTypes.OfType <GenericType>().Any()) { delegateCtor = TypeBuilder.GetConstructor(type, delegateCtor); } else { delegateCtor = type.GetConstructor(new[] { typeof(object), typeof(IntPtr) }); } } else { var type = GetFuncType(this.ArgumentTypes.Count + 1); delegateCtor = type.GetConstructor(new[] { typeof(object), typeof(IntPtr) }); type = type.MakeGenericType(TypeLookup(this.ArgumentTypes).Concat(new[] { TypeLookup(this.MemberType) }).ToArray()); if (this._argumentTypes.OfType <GenericType>().Any() || this.MemberType is GenericType) { delegateCtor = TypeBuilder.GetConstructor(type, delegateCtor); } else { delegateCtor = type.GetConstructor(new[] { typeof(object), typeof(IntPtr) }); } } var returnLabel = il.DefineLabel(); il.Emit(OpCodes.Ldc_I4, this.ArgumentTypes.Count); il.Emit(OpCodes.Newarr, typeof(object)); il.Emit(OpCodes.Stloc, parameterArrayVar); for (int i = 1; i <= this.ArgumentTypes.Count; i++) { il.Emit(OpCodes.Ldloc, parameterArrayVar); il.Emit(OpCodes.Ldc_I4, i - 1); il.Emit(OpCodes.Ldarg, i); var type = TypeLookup(this._argumentTypes[i - 1]); il.Emit(OpCodes.Box, type); il.Emit(OpCodes.Stelem_Ref); } il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldstr, this.MemberName); il.Emit(OpCodes.Ldarg_0); if (this.ImplementationMethod.IsGenericMethod) { il.Emit(OpCodes.Ldftn, this.ImplementationMethod.MakeGenericMethod(this.GenericParameters.Select(p => p.AsType()).ToArray())); } else { il.Emit(OpCodes.Ldftn, this.ImplementationMethod); } il.Emit(OpCodes.Newobj, delegateCtor); il.Emit(OpCodes.Ldloc, parameterArrayVar); il.Emit(OpCodes.Newobj, interceptionContextCtor); il.Emit(OpCodes.Stloc, ctxVar); List <MethodInfo> interceptors = new List <MethodInfo>(); if (isAsync) { interceptors = typeBuilder.BaseType.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance) .Where(p => !p.IsPrivate && p.GetCustomAttributes(typeof(MethodInterceptorAttribute), true).Any() && p.GetParameters().Count() == 1 && p.GetParameters().First().ParameterType == typeof(AsyncInterceptionContext) && p.ReturnType == typeof(Task)) .ToList(); } else { interceptors = typeBuilder.BaseType.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance) .Where(p => !p.IsPrivate && p.GetCustomAttributes(typeof(MethodInterceptorAttribute), true).Any() && p.GetParameters().Count() == 1 && p.GetParameters().First().ParameterType == typeof(InterceptionContext)) .ToList(); } var registerMethod = ctxType.GetMethod("RegisterInterceptor"); foreach (var item in interceptors) { il.Emit(OpCodes.Ldloc, ctxVar); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldftn, item); if (isAsync) { il.Emit(OpCodes.Newobj, typeof(Func <AsyncInterceptionContext, Task>).GetConstructor(new[] { typeof(object), typeof(IntPtr) })); } else { il.Emit(OpCodes.Newobj, typeof(Action <InterceptionContext>).GetConstructor(new[] { typeof(object), typeof(IntPtr) })); } il.Emit(OpCodes.Ldc_I4, (int)item.GetCustomAttributes(typeof(MethodInterceptorAttribute), true).OfType <MethodInterceptorAttribute>().First().InterceptionMode); if (isAsync) { il.Emit(OpCodes.Newobj, typeof(DelegateAsyncMethodInterceptor).GetConstructors().First()); } else { il.Emit(OpCodes.Newobj, typeof(DelegateMethodInterceptor).GetConstructors().First()); } il.EmitCall(OpCodes.Callvirt, registerMethod, null); } if (isAsync) { var taskType = TypeLookup(this.MemberType).GetTypeInfo().IsGenericType ? TypeLookup(this.MemberType).GetGenericArguments().First() : typeof(object); il.Emit(OpCodes.Ldloc, ctxVar); il.EmitCall(OpCodes.Callvirt, ctxType.GetMethod("ExecuteAsync").MakeGenericMethod(taskType), null); } else { il.Emit(OpCodes.Ldloc, ctxVar); il.EmitCall(OpCodes.Callvirt, typeof(InterceptionContext).GetMethod("Execute"), null); if (this.MemberType != null) { il.Emit(OpCodes.Ldloc, ctxVar); il.Emit(OpCodes.Callvirt, typeof(InterceptionContext).GetProperty("Result").GetGetMethod()); var returnType = TypeLookup(this.MemberType); if (returnType.GetTypeInfo().IsValueType || returnType.IsGenericParameter) { il.Emit(OpCodes.Unbox_Any, TypeLookup(this.MemberType)); } else { il.Emit(OpCodes.Castclass, returnType); } } } il.Emit(OpCodes.Ret); }