Beispiel #1
0
        private List <MethodInfo> GetMethod(Type t)
        {
            List <MethodInfo> list       = new List <MethodInfo>();
            List <string>     methodList = new List <string>();
            Type ot = typeof(Object);

            while (t != null && t != ot)
            {
                var methods = t.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly);
                foreach (var met in methods)
                {
                    if (!met.IsAbstract)
                    {
                        StringBuilder strb = new StringBuilder();
                        if (met.IsStatic)
                        {
                            strb.Append("static ");
                        }
                        strb.Append(met.ReturnType != null ? met.ReturnType.FullName : "void");
                        strb.Append(" ");
                        strb.Append(met.Name);
                        strb.Append("(");
                        var parameterTypes = AopUtils.GetParameterType(met);
                        foreach (var pt in parameterTypes)
                        {
                            strb.Append(pt.FullName + ", ");
                        }
                        if (parameterTypes.Length > 0)
                        {
                            strb.Remove(strb.Length - 2, 2);
                        }
                        strb.Append(")");
                        string methodkey = strb.ToString();
                        if (!methodList.Contains(methodkey))
                        {
                            methodList.Add(methodkey);
                            list.Add(met);
                        }
                    }
                }

                t = t.BaseType;
            }

            return(list);
        }
Beispiel #2
0
        private List <MethodInfo> GetOverrideMethods(MethodInfo meth, Type[] interfaceTypes)
        {
            List <MethodInfo> list = new List <MethodInfo>(interfaceTypes != null ? interfaceTypes.Length : 0);

            if (interfaceTypes != null && interfaceTypes.Length > 0)
            {
                foreach (var t in interfaceTypes)
                {
                    var interfaceMeth = t.GetMethod(meth.Name, AopUtils.GetParameterType(meth));
                    if (interfaceMeth != null && interfaceMeth.ReturnType == meth.ReturnType)
                    {
                        list.Add(interfaceMeth);
                    }
                }
            }

            return(list);
        }
Beispiel #3
0
        /// <summary>
        /// 获取指定类型的代理类型
        /// </summary>
        /// <param name="tagetType">指定类型</param>
        /// <returns>返回代理类型</returns>
        public Type GetProxyType(Type tagetType)
        {
            Type proxyType = null;

            if (tagetType != null && tagetType.IsClass && !tagetType.IsAbstract &&
                tagetType.IsPublic && !tagetType.IsSealed &&
                tagetType.IsVisible)
            {
                var tagetCtors = tagetType.GetConstructors(BindingFlags.Instance | BindingFlags.Public);
                if (tagetCtors == null || tagetCtors.Length == 0)
                {
                    return(proxyType);
                }

                using (this.m_rwLock.GetReadLock())
                {
                    this.m_proxyTypeDic.TryGetValue(tagetType, out proxyType);
                }
                if (proxyType != null)
                {
                    return(proxyType);
                }

                using (this.m_rwLock.GetWriteLock())
                {
                    this.m_proxyTypeDic.TryGetValue(tagetType, out proxyType);
                    if (proxyType != null)
                    {
                        return(proxyType);
                    }
                    var interfaceTypes = tagetType.GetInterfaces();
                    var typeBuilder    = this.m_moduleBuilder.DefineType(this.GetDynamicName(tagetType), tagetType.Attributes, tagetType, interfaceTypes);

                    var tagetTypeField = typeBuilder.DefineField("m_tagetType", typeof(Type), FieldAttributes.Private);
                    // 构造器
                    foreach (var baseCtor in tagetCtors)
                    {
                        var paramets              = AopUtils.GetParameterType(baseCtor);
                        ConstructorBuilder ctor   = typeBuilder.DefineConstructor(baseCtor.Attributes, baseCtor.CallingConvention, paramets);
                        ILGenerator        ctorIL = ctor.GetILGenerator();
                        ctorIL.Emit(OpCodes.Ldarg_0);
                        for (int i = 0; i < paramets.Length; i++)
                        {
                            ctorIL.Emit(OpCodes.Ldarg, i + 1);
                        }
                        ctorIL.Emit(OpCodes.Call, baseCtor);
                        ctorIL.Emit(OpCodes.Ldarg_0);
                        ctorIL.Emit(OpCodes.Ldarg_0);
                        ctorIL.Emit(OpCodes.Callvirt, typeof(Object).GetMethod("GetType"));
                        ctorIL.Emit(OpCodes.Callvirt, typeof(Type).GetMethod("get_BaseType"));
                        ctorIL.Emit(OpCodes.Stfld, tagetTypeField);
                        ctorIL.Emit(OpCodes.Ret);
                    }
                    //方法
                    var methods        = this.GetMethod(tagetType);
                    var aopContextType = typeof(AopContext);
                    foreach (var met in methods)
                    {
                        var intefacemethlist = this.GetOverrideMethods(met, interfaceTypes);
                        if (!met.IsVirtual && intefacemethlist.Count == 0)
                        {
                            continue;
                        }

                        var parameterTypes        = AopUtils.GetParameterType(met);
                        MethodAttributes methattr = MethodAttributes.FamANDAssem | MethodAttributes.Family | MethodAttributes.Virtual | MethodAttributes.HideBySig;
                        if ((met.Attributes & MethodAttributes.Final) == MethodAttributes.Final)
                        {
                            methattr = methattr | MethodAttributes.VtableLayoutMask;
                        }
                        var          methodBuilder      = typeBuilder.DefineMethod(met.Name, methattr, CallingConventions.Standard | CallingConventions.HasThis, met.ReturnType, parameterTypes);
                        ILGenerator  il                 = methodBuilder.GetILGenerator();
                        var          aAopInfoLocal      = il.DeclareLocal(typeof(AopInfoModel)); //0
                        var          aopContextLocal    = il.DeclareLocal(aopContextType);       //1
                        var          currentMethodLocal = il.DeclareLocal(typeof(MethodBase));   //2
                        var          nameLocal          = il.DeclareLocal(typeof(string));       //3
                        var          paramsLocal        = il.DeclareLocal(typeof(Type[]));       //4
                        LocalBuilder returnLocal        = null;                                  //5
                        if (met.ReturnType != null && met.ReturnType != typeof(void))
                        {
                            returnLocal = il.DeclareLocal(met.ReturnType);
                        }
                        var   exLocal   = il.DeclareLocal(typeof(Exception));//5.6
                        Label endOfMthd = il.DefineLabel();

                        //il.Emit(OpCodes.Nop);
                        il.Emit(OpCodes.Newobj, typeof(AopInfoModel).GetConstructor(Type.EmptyTypes));
                        il.Emit(OpCodes.Stloc, aAopInfoLocal);
                        il.Emit(OpCodes.Ldloc, aAopInfoLocal);
                        il.Emit(OpCodes.Ldc_I4, this.m_classId);
                        il.Emit(OpCodes.Callvirt, typeof(AopInfoModel).GetMethod("set_ClassId"));
                        //il.Emit(OpCodes.Nop);
                        il.Emit(OpCodes.Newobj, aopContextType.GetConstructor(Type.EmptyTypes));
                        il.Emit(OpCodes.Stloc, aopContextLocal);
                        il.Emit(OpCodes.Call, typeof(MethodBase).GetMethod("GetCurrentMethod", BindingFlags.Static | BindingFlags.Public));
                        il.Emit(OpCodes.Stloc, currentMethodLocal);
                        il.Emit(OpCodes.Ldloc, currentMethodLocal);
                        il.Emit(OpCodes.Callvirt, typeof(MemberInfo).GetMethod("get_Name"));
                        il.Emit(OpCodes.Stloc, nameLocal);
                        il.Emit(OpCodes.Ldloc, currentMethodLocal);
                        il.Emit(OpCodes.Call, m_GetParameterTypeMethod);
                        il.Emit(OpCodes.Stloc, paramsLocal);
                        if (returnLocal != null)
                        {
                            if (!met.ReturnType.IsValueType)
                            {
                                il.Emit(OpCodes.Ldnull);
                                il.Emit(OpCodes.Stloc, returnLocal);
                            }
                        }
                        il.Emit(OpCodes.Ldnull);
                        il.Emit(OpCodes.Stloc, exLocal);
                        il.Emit(OpCodes.Ldloc, aopContextLocal);
                        il.Emit(OpCodes.Ldarg_0);
                        il.Emit(OpCodes.Ldfld, tagetTypeField);
                        il.Emit(OpCodes.Callvirt, aopContextType.GetMethod("set_TagetType"));
                        //il.Emit(OpCodes.Nop);
                        il.Emit(OpCodes.Ldloc, aopContextLocal);
                        il.Emit(OpCodes.Ldarg_0);
                        il.Emit(OpCodes.Ldfld, tagetTypeField);
                        il.Emit(OpCodes.Ldloc, nameLocal);
                        il.Emit(OpCodes.Ldloc, paramsLocal);
                        il.Emit(OpCodes.Callvirt, typeof(Type).GetMethod("GetMethod", new Type[] { typeof(string), typeof(Type[]) }));
                        il.Emit(OpCodes.Callvirt, aopContextType.GetMethod("set_Method"));
                        //il.Emit(OpCodes.Nop);
                        il.Emit(OpCodes.Ldloc, aopContextLocal);
                        il.Emit(OpCodes.Ldarg_0);
                        il.Emit(OpCodes.Callvirt, aopContextType.GetMethod("set_Taget"));
                        //il.Emit(OpCodes.Nop);
                        il.Emit(OpCodes.Ldloc, aopContextLocal);
                        il.Emit(OpCodes.Ldc_I4, parameterTypes.Length);
                        il.Emit(OpCodes.Newarr, typeof(Object));
                        il.Emit(OpCodes.Callvirt, aopContextType.GetMethod("set_Parameters"));
                        //il.Emit(OpCodes.Nop);
                        for (int i = 0; i < parameterTypes.Length; i++)
                        {
                            il.Emit(OpCodes.Ldloc, aopContextLocal);
                            il.Emit(OpCodes.Callvirt, aopContextType.GetMethod("get_Parameters"));
                            il.Emit(OpCodes.Ldc_I4, i);
                            il.Emit(OpCodes.Ldarg, i + 1);
                            if (parameterTypes[i].IsValueType)
                            {
                                il.Emit(OpCodes.Box, parameterTypes[i]);
                            }
                            il.Emit(OpCodes.Stelem_Ref);
                        }
                        il.Emit(OpCodes.Ldloc, aAopInfoLocal);
                        il.Emit(OpCodes.Ldloc, aopContextLocal);
                        il.Emit(OpCodes.Call, m_OnExecutingMethod);
                        //il.Emit(OpCodes.Nop);

                        var exBlock = il.BeginExceptionBlock();
                        il.Emit(OpCodes.Ldarg_0);
                        for (int i = 0; i < parameterTypes.Length; i++)
                        {
                            il.Emit(OpCodes.Ldarg, i + 1);
                        }
                        il.Emit(OpCodes.Call, met);
                        if (returnLocal != null)
                        {
                            il.Emit(OpCodes.Stloc, returnLocal);
                        }
                        il.Emit(OpCodes.Leave_S, endOfMthd);
                        il.BeginCatchBlock(typeof(Exception));
                        il.Emit(OpCodes.Stloc, exLocal);
                        il.Emit(OpCodes.Ldloc, aAopInfoLocal);
                        il.Emit(OpCodes.Ldloc, aopContextLocal);
                        il.Emit(OpCodes.Ldloc, exLocal);
                        il.Emit(OpCodes.Call, m_OnExceptionMethod);
                        il.Emit(OpCodes.Ldloc, exLocal);
                        il.Emit(OpCodes.Throw);
                        il.EndExceptionBlock();

                        il.MarkLabel(endOfMthd);
                        il.Emit(OpCodes.Ldloc, aAopInfoLocal);
                        il.Emit(OpCodes.Ldloc, aopContextLocal);
                        if (returnLocal != null)
                        {
                            il.Emit(OpCodes.Ldloc, returnLocal);
                            if (met.ReturnType.IsValueType)
                            {
                                il.Emit(OpCodes.Box, met.ReturnType);
                            }
                        }
                        else
                        {
                            il.Emit(OpCodes.Ldnull);
                        }
                        il.Emit(OpCodes.Call, m_OnResultMethod);
                        if (returnLocal != null)
                        {
                            il.Emit(OpCodes.Ldloc, returnLocal);
                        }
                        il.Emit(OpCodes.Ret);

                        foreach (var me in intefacemethlist)
                        {
                            typeBuilder.DefineMethodOverride(methodBuilder, me);
                        }
                    }
#if NETSTANDARD
                    proxyType = typeBuilder.CreateTypeInfo();
#else
                    proxyType = typeBuilder.CreateType();
#endif
                }
                this.m_proxyTypeDic[tagetType] = proxyType;
            }

            return(proxyType ?? tagetType);
        }