Example #1
0
        private static DBSessionAttribute GetMethodTransactionAttribute(MethodInfo method)
        {
            DBSessionAttribute attr = method.GetCustomAttribute <DBSessionAttribute>();

            return(attr);
        }
Example #2
0
        private static DBSessionAttribute GetClassTransactionAttribute(Type type)
        {
            DBSessionAttribute attr = type.GetCustomAttribute <DBSessionAttribute>();

            return(attr);
        }
Example #3
0
        /// <summary>
        /// 织入代理代码
        /// </summary>
        /// <param name="bean"></param>
        private static string WavingProxyCode()
        {
            //命名空间预设
            StringBuilder sb = new StringBuilder();

            sb.Append(" using System;\n using LTCingFW;\n using System.Threading;\n");
            sb.Append(" using log4net;\n");//log2
            sb.Append(" namespace " + FWConfigs.proxyNameSpace + " { \n ");
            foreach (FwInstanceBean bean in LTCingFWSet.Beans)
            {
                #region 代理类

                String   bean_name           = bean.Name;
                String   type_full_name      = bean.Type;
                String[] sps                 = type_full_name.Split('.');
                String   LTCingFW_proxy_name = "_proxy_" + sps[sps.Length - 1];
                sb.Append(String.Format(" public class {0} : {1} {{  \n", LTCingFW_proxy_name, type_full_name));
                //3 sb.Append(String.Format(" private static readonly ILog logger = LogManager.GetLogger(typeof({0}));", LTCingFW_proxy_name));

                #region 代理方法

                Type         type = bean.BelongAssembly.GetType(type_full_name);
                MethodInfo[] mtds = type.GetMethods(BindingFlags.Public | BindingFlags.Instance);
                foreach (MethodInfo mi in mtds)
                {
                    #region 方法筛选
                    //去除掉队GetType、GetHashCode、Equals、ToString方法的重写
                    if (mi.Name == "GetType" || mi.Name == "GetHashCode" || mi.Name == "Equals" || mi.Name == "ToString")
                    {
                        continue;
                    }
                    //去除属性方法的重写
                    if (mi.Name.IndexOf("get_") > -1 || mi.Name.IndexOf("set_") > -1)
                    {
                        continue;
                    }
                    //获取切面
                    FwAopBean aspect = GetMethodAspect(type_full_name, mi);
                    //获取DBSessionAttribute
                    DBSessionAttribute dbSessionAttr = GetMethodTransactionAttribute(mi);
                    if (dbSessionAttr == null)
                    {
                        dbSessionAttr = GetClassTransactionAttribute(type);
                    }
                    #endregion

                    if (mi.Name == "NoticeDataChangedCallBack")
                    {
                    }
                    if (!mi.IsVirtual)
                    {
                        continue;
                    }
                    #region 设置方法名、参数、返回值还原
                    StringBuilder generics = new StringBuilder("");
                    if (mi.IsGenericMethod)
                    {
                        generics.Append("<");
                        foreach (Type item in mi.GetGenericArguments())
                        {
                            generics.Append(item.Name);
                            generics.Append(",");
                        }
                        generics.Remove(generics.Length - 1, 1);
                        generics.Append(">");
                    }

                    string method_head = String.Format("\n public override {0} {1} {2}( ", FwUtilFunc.GetRegularReturnType(mi.ReturnType), mi.Name, generics.ToString());
                    sb.Append(method_head);
                    #endregion

                    #region 方法内前置内容
                    ParameterInfo[] paramInfos = mi.GetParameters();
                    StringBuilder   paramStr   = new StringBuilder(" ");
                    StringBuilder   objStr     = new StringBuilder(" ");
                    for (int i = 0; i < paramInfos.Length; i++)
                    {
                        sb.Append(FwUtilFunc.GetRegularReturnType(paramInfos[i].ParameterType));

                        sb.Append(" para").Append(i).Append(" ,");
                        if (paramInfos[i].ParameterType.IsByRef)
                        {
                            paramStr.Append(" ref");
                        }
                        paramStr.Append(" para").Append(i).Append(" ,");
                        objStr.Append(" para").Append(i).Append(" ,");
                    }
                    paramStr.Remove(paramStr.Length - 1, 1);
                    sb.Remove(sb.Length - 1, 1);
                    sb.Append(")");
                    //if (mi.ReturnType.FullName == null)
                    //{
                    //    sb.Append(" where T : OrmBaseModel");
                    //}
                    sb.Append("{\n");
                    sb.Append(" object[] paras = new object[]{ ").Append(objStr).Append("};\n");
                    sb.Append(" bool outerSession = false;\n");
                    sb.Append(" DBSession session = null;\n");
                    if (mi.ReturnType.FullName != "System.Void")
                    {
                        sb.Append(" object r = null; \n");
                    }

                    sb.Append(" try \n {\n");
                    sb.Append(" if (!LTCingFWSet.ThreadContextDic.ContainsKey(Thread.CurrentThread.ManagedThreadId)) {\n");
                    sb.Append(" LTCingFWSet.ThreadContextDic.Add(Thread.CurrentThread.ManagedThreadId, new LTCingFW.beans.ThreadContext());\n");
                    sb.Append(" LTCingFWSet.ThreadContextDic[Thread.CurrentThread.ManagedThreadId].MethodName = \"");
                    sb.Append(type_full_name).Append(".").Append(mi.Name).Append("\";");
                    sb.Append(" \n}\n");
                    sb.Append(" else if(LTCingFWSet.ThreadContextDic[Thread.CurrentThread.ManagedThreadId].DBSession != null)\n");
                    sb.Append(" {\n  outerSession = true;\n}\n");
                    #endregion

                    #region 方法前部分
                    //进入过程ERROR置为空
                    sb.Append(" LTCingFWSet.ThreadContextDic[Thread.CurrentThread.ManagedThreadId].Error = null;\n");
                    //Transaction判定
                    if (dbSessionAttr != null)
                    {
                        sb.Append(" if(!outerSession){\n");
                        sb.Append(String.Format("session = DBSession.OpenSession(\"{0}\",{1});\n", dbSessionAttr.DbAlias, dbSessionAttr.OpenTransaction.ToString().ToLower()));
                        sb.Append("LTCingFWSet.ThreadContextDic[Thread.CurrentThread.ManagedThreadId].DBSession = session;\n");
                        sb.Append(" }\n");
                    }
                    #region 前AOP方法
                    if (aspect != null)
                    {
                        if (FwUtilFunc.StringIsNotEmpty(aspect.BeforeMethod))
                        {
                            //检测切入函数是否为公共和静态
                            int        index          = aspect.BeforeMethod.LastIndexOf('.');
                            String     full_type_name = aspect.BeforeMethod.Substring(0, index);
                            String     method_name    = aspect.BeforeMethod.Substring(index + 1);
                            Type       typeCls        = Assembly.GetEntryAssembly().GetType(full_type_name);
                            MethodInfo mtdInfo        = typeCls.GetMethod(method_name);
                            if (!mtdInfo.IsPublic || !mtdInfo.IsStatic)
                            {
                                throw new Exception("切入函数需为公共静态函数");
                            }
                            //加入切点函数
                            sb.Append(aspect.BeforeMethod).Append("(paras);\n");
                        }
                    }
                    #endregion

                    #endregion

                    #region 原方法,中间部分
                    if (mi.ReturnType.FullName != "System.Void")
                    {
                        sb.Append(" r = ").Append("base.").Append(mi.Name);
                        if (mi.ReturnType.FullName == null)
                        {
                            sb.Append("<T> ");
                        }
                        sb.Append("(").Append(paramStr).Append(");\n");
                    }
                    else
                    {
                        sb.Append("base.").Append(mi.Name);
                        sb.Append("(").Append(paramStr).Append(");\n");
                    }
                    #endregion

                    #region 方法后部分
                    sb.Append(" }\n catch (Exception ex) { \n ");
                    //sb.Append(" logger.Warn(\"Proxy_InnerException:\"+ex.Message+ex.StackTrace);\n");
                    sb.Append("   if(session != null && session.Transaction != null) \n{session.RollBack(); session.Close();\n}\n");
                    //sb.Append(" LTCingFWSet.ErrList.Add(ex); \n");//伴随框架的错误处理线程,一起注掉了
                    sb.Append("   LTCingFWSet.ThreadContextDic[Thread.CurrentThread.ManagedThreadId].Error = ex;\n");
                    sb.Append("   throw ex; \n");
                    sb.Append(" }\n ");
                    sb.Append(" finally \n { \n   ");
                    sb.Append("   if(!outerSession)\n{\n");
                    sb.Append("     if(session != null && !session.IsClosed()) \n{ \n ");
                    sb.Append("       session.Close(); \n}\n");
                    sb.Append("     if(LTCingFWSet.ThreadContextDic.ContainsKey(Thread.CurrentThread.ManagedThreadId))\n{ \n");
                    sb.Append("       LTCingFWSet.ThreadContextDic[Thread.CurrentThread.ManagedThreadId].DBSession = null;\n}\n");
                    sb.Append("   }\n");

                    #region 后AOP方法
                    if (aspect != null)
                    {
                        if (FwUtilFunc.StringIsNotEmpty(aspect.AfterMethod))
                        {
                            //检测切点函数是否为公共和静态
                            int        index          = aspect.AfterMethod.LastIndexOf('.');
                            String     full_type_name = aspect.AfterMethod.Substring(0, index);
                            String     method_name    = aspect.AfterMethod.Substring(index + 1);
                            Type       typeCls        = Assembly.GetEntryAssembly().GetType(full_type_name);
                            MethodInfo mtdInfo        = typeCls.GetMethod(method_name);
                            if (!mtdInfo.IsPublic || !mtdInfo.IsStatic)
                            {
                                throw new Exception("切入函数需为公共静态函数");
                            }
                            //加入切点函数
                            sb.Append(aspect.AfterMethod).Append("(paras);\n");
                        }
                        if (FwUtilFunc.StringIsEmpty(aspect.BeforeMethod) && FwUtilFunc.StringIsEmpty(aspect.AfterMethod))
                        {
                            throw new Exception("切面需要一个前置切入函数或一个后置切入函数");
                        }
                    }
                    #endregion

                    sb.Append(" }\n");
                    //返回值
                    if (mi.ReturnType.FullName != "System.Void")
                    {
                        sb.Append(" return (").Append(FwUtilFunc.GetRegularReturnType(mi.ReturnType)).Append(") r; \n");
                    }
                    //结束
                    sb.Append("}\n");
                    #endregion
                }
                #endregion

                sb.Append("}\n");

                #endregion

                //记录日志
                logger.Info(String.Format("create Proxy for bean[{0}]", bean.Name));
                bean.ProxyType = FWConfigs.proxyNameSpace + "." + LTCingFW_proxy_name;
            }
            //命名空间结束
            sb.Append(" } \n");

            return(sb.ToString());
        }