示例#1
0
        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);
        }
示例#2
0
        public override void Implement(DynamicTypeBuilder config, TypeBuilder typeBuilder)
        {
            var addMethodIL = AddMethod.GetILGenerator();

            GenerateHandlerMethods(BackingField, addMethodIL, true);

            var removeMethodIL = RemoveMethod.GetILGenerator();

            GenerateHandlerMethods(BackingField, removeMethodIL, false);
        }
示例#3
0
        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());
        }
示例#4
0
        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());
            }
        }
示例#5
0
        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);
            }
        }
示例#6
0
 public abstract void Implement(DynamicTypeBuilder config, TypeBuilder typeBuilder);
示例#7
0
 public override void Implement(DynamicTypeBuilder config, System.Reflection.Emit.TypeBuilder typeBuilder)
 {
 }
示例#8
0
 protected abstract void Implement(DynamicTypeBuilder config, TypeBuilder typeBuilder, ILGenerator il);
示例#9
0
        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);
        }