Ejemplo n.º 1
0
        /// <summary>
        ///  创建非侵入式代理类型
        /// </summary>
        /// <typeparam name="TType"></typeparam>
        /// <param name="implementationType"></param>
        /// <param name="noAction"></param>
        /// <param name="parameters"></param>
        /// <returns></returns>
        public static TType CreateInterceptor <TType>(Type implementationType, NoActionAttributeModel noAction, params object[] parameters)
            where TType : class
        {
            // 生成代理类型
            Type objtype = CreateProxyClassTypeNoAttribute(implementationType, noAction);

            // 返回实例
            return(Activator.CreateInstance(implementationType.IsGenericType ? EmitHelper.CreateGenericClass(objtype, implementationType) : objtype, parameters) as TType);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// 通过非侵入式来生成代理类型
        /// </summary>
        /// <param name="interfaceType">实现的接口或继承</param>
        /// <param name="implementationType">实现的类型</param>
        /// <param name="Inherit">是否通过继承生成</param>
        /// <returns></returns>
        public static Type CreateProxyClassTypeNoAttribute(Type implementationType, NoActionAttributeModel noAction)
        {
            Type        type = implementationType;
            TypeBuilder typeBuilder;

            if (CacheProxyClass.ContainsKey(implementationType))
            {
                return(CacheProxyClass[type]);
            }
            typeBuilder = moduleBuilder.DefineType("CZGLAOP." + type.Name + _TypeName, type.Attributes, type);

            // 判断是否为泛型,如果是则构造其为泛型
            bool isGeneric = EmitHelper.DefineGenericParameters(typeBuilder, type);

            // 生成代理类型
            Type proxyType = ActionInterceptor(type, typeBuilder, true, noAction);

            CacheProxyClass.TryAdd(implementationType, proxyType);
            return(proxyType);
        }
Ejemplo n.º 3
0
        public static Dictionary <Type, FieldBuilder> GetActionAttribute(TypeBuilder typeBuilder, NoActionAttributeModel noAction)
        {
            Dictionary <Type, FieldBuilder> dic = new Dictionary <Type, FieldBuilder>();

            foreach (var item in noAction.Actions)
            {
                var actionType = item.Value;
                dic.Add(actionType, typeBuilder.DefineField("_" + actionType.Name, actionType, FieldAttributes.Private | FieldAttributes.InitOnly));
            }
            return(dic);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// 拦截 Action 并且生成类型
        /// </summary>
        /// <typeparam name="TType">被代理的类</typeparam>
        /// <param name="parentType">父类</param>
        /// <param name="typeBuilder">生成器</param>
        /// <param name="Inherit">是否属于类继承</param>
        /// <param name="noAction">非嵌入式代理时</param>
        public static Type ActionInterceptor(Type parentType, TypeBuilder typeBuilder, bool Inherit, NoActionAttributeModel noAction = null)
        {
            // 生成字段,用于存放拦截的上下文信息
            FieldBuilder aspectContextField = typeBuilder.DefineField("_" + nameof(AspectContextBody), typeof(AspectContext), FieldAttributes.Private | FieldAttributes.InitOnly);

            // 存储类成员使用的特性拦截器
            Dictionary <Type, FieldBuilder> fieldList;

            var properties = parentType.GetProperties();
            var methods    = parentType.GetMethods();

            fieldList = noAction == null?GetActionAttribute(properties, methods, typeBuilder) : GetActionAttribute(typeBuilder, noAction);

            ConstructorInfo[] constructorInfos = parentType.GetConstructors();

            // 代理类实现与被代理类一致的构造函数
            // 代理类初始化各个拦截器
            foreach (var item in constructorInfos)
            {
                ParameterInfo[] paramTypes         = item.GetParameters();
                var             constructorBuilder = typeBuilder.DefineConstructor(
                    item.Attributes,
                    item.CallingConvention,
                    paramTypes.Select(x => x.ParameterType).ToArray());

                var conIL = constructorBuilder.GetILGenerator();

                if (paramTypes.Length != 0)
                {
                    foreach (var itemtmp in paramTypes)
                    {
                        conIL.DeclareLocal(itemtmp.ParameterType);
                    }
                }

                // 实例函数使用 从 Ldarg.1 开始
                // Ldarg.0 属于 this
                conIL.Emit(OpCodes.Ldarg_0);

                // 三个步骤:
                // * 处理构造函数参数
                // * 调用被代理类的构造函数并传递参数
                // * 实例化拦截器上下文、为上下文设置属性、构造拦截器

                // 如果构造函数有参数的话
                if (paramTypes.Length > 0)
                {
                    MethodParamters(paramTypes.Length, conIL);// 处理所有参数
                }
                // 调用父类的构造函数
                conIL.Emit(OpCodes.Call, item);

                // 实例化上下文
                conIL.Emit(OpCodes.Ldarg_0); // 将索引为 0 的自变量加载到计算堆栈上。
                conIL.Emit(OpCodes.Newobj, typeof(AspectContextBody).GetConstructor(new Type[0] {
                }));
                conIL.Emit(OpCodes.Stfld, aspectContextField);  // 用新值替换在对象引用或指针的字段中存储的值。

                // 为上下文设置属性
                // 设置当前代理类型
                conIL.Emit(OpCodes.Ldarg_0);
                conIL.Emit(OpCodes.Ldfld, aspectContextField);
                conIL.Emit(OpCodes.Castclass, typeof(AspectContextBody));
                conIL.Emit(OpCodes.Ldarg_0);
                conIL.Emit(OpCodes.Call, parentType.GetMethod(nameof(GetType)));
                conIL.Emit(OpCodes.Callvirt, typeof(AspectContextBody).GetMethod($"set_{nameof(AspectContextBody.Type)}"));

                // 设置构造函数参数列表
                conIL.Emit(OpCodes.Ldarg_0);
                conIL.Emit(OpCodes.Ldfld, aspectContextField);
                conIL.Emit(OpCodes.Castclass, typeof(AspectContextBody));
                EmitHelper.EmitArr(conIL, paramTypes, typeof(object));
                conIL.Emit(OpCodes.Callvirt, typeof(AspectContextBody).GetMethod($"set_{nameof(AspectContextBody.ConstructorParamters)}"));



                // 实例化所有拦截器
                NewConstructor(conIL, fieldList);
                conIL.Emit(OpCodes.Ret);
            }

            // 代理拦截方法
            foreach (var item in methods)
            {
                // 判断是否为侵入式代理
                // 是否设置了拦截器的方法
                ActionAttribute actionAttr;
                Type            actionAttrType;
                if (noAction == null)
                {
                    actionAttr = (ActionAttribute)item.GetCustomAttributes().FirstOrDefault(x => x.GetType().BaseType == typeof(ActionAttribute));
                    if (actionAttr is null)
                    {
                        continue;
                    }
                    actionAttrType = actionAttr.GetType();
                }
                else
                {
                    string actionName;
                    if (!noAction.MethodNames.TryGetValue(item, out actionName))
                    {
                        continue;
                    }
                    actionAttrType = noAction.Actions[actionName];
                }

                // 获取方法的参数
                Type[] types      = item.GetParameters().Select(x => x.ParameterType).ToArray();
                Type   returnType = item.ReturnType;

                MethodBuilder methodBuilder = typeBuilder.DefineMethod(
                    item.Name,
                    MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.HideBySig,
                    CallingConventions.Standard,
                    returnType,
                    types);

                // 判断是否为泛型方法并生成泛型类型
                bool isGeneric = EmitHelper.CreateGenericMethod(methodBuilder, item);

                var iL = methodBuilder.GetILGenerator();

                // 生成代理方法
                MethodProxy(iL, item, aspectContextField, fieldList[actionAttrType], actionAttrType);

                // 如果属于继承,则需要重写方法
                if (Inherit)
                {
                    typeBuilder.DefineMethodOverride(methodBuilder, item);
                }
            }

            // 代理拦截属性
            foreach (var item in properties)
            {
                // 四种情况:没有设置拦截器、属性设置拦截器、属性的get设置拦截器、属性的set设置拦截器
                // 不管构造器是否为私有都可以代理
                // 是否设置了拦截器的方法
                int mode = 0;

                MethodInfo getMethodInfo = default;
                MethodInfo setMethodInfo = default;

                // 判断属性有没有使用拦截器

                var actionAttr = (ActionAttribute)item.GetCustomAttributes().FirstOrDefault(x => x.GetType().BaseType == typeof(ActionAttribute));

                if (item.CanRead)
                {
                    getMethodInfo = item.GetGetMethod(true);
                }
                if (item.CanWrite)
                {
                    setMethodInfo = item.GetSetMethod(true);
                }


                if (actionAttr is null)
                {
                    mode = 0b000;
                    if (getMethodInfo != null)
                    {
                        if (getMethodInfo.GetCustomAttributes().FirstOrDefault(x => x.GetType().BaseType == typeof(ActionAttribute)) != null)
                        {
                            mode |= 0b001;
                        }
                    }
                    if (setMethodInfo != null)
                    {
                        if ((ActionAttribute)setMethodInfo.GetCustomAttributes().FirstOrDefault(x => x.GetType().BaseType == typeof(ActionAttribute)) != null)
                        {
                            mode |= 0b010;
                        }
                    }
                }
                else
                {
                    mode = 0b001 | 0b010;
                }

                if (mode == 0b000)
                {
                    continue;
                }

                // 代理属性
                switch (mode)
                {
                case 0b11:
                    GetBuilder();
                    SetBuilder();
                    break;

                case 0b001:
                    GetBuilder();
                    break;

                case 0b010:
                    SetBuilder();
                    break;
                }

                void GetBuilder()
                {
                    MethodBuilder setMethodBuilder = typeBuilder.DefineMethod(
                        getMethodInfo.Name,
                        MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.HideBySig,
                        getMethodInfo.CallingConvention,
                        getMethodInfo.ReturnType,
                        null);

                    PropertyGetProxy(setMethodBuilder.GetILGenerator(), parentType, getMethodInfo, item, aspectContextField, fieldList[actionAttr.GetType()], actionAttr);
                }

                void SetBuilder()
                {
                    MethodBuilder getMethodBuilder = typeBuilder.DefineMethod(
                        setMethodInfo.Name,
                        MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.HideBySig,
                        setMethodInfo.CallingConvention,
                        setMethodInfo.ReturnType,
                        setMethodInfo.GetParameters().Select(x => x.ParameterType).ToArray());

                    PropertyGetProxy(getMethodBuilder.GetILGenerator(), parentType, setMethodInfo, item, aspectContextField, fieldList[actionAttr.GetType()], actionAttr);
                }
            }

            return(typeBuilder.CreateTypeInfo());
        }