//} /// <summary> /// 查找AOP配置信息 /// </summary> private static void lookForConfigAspect_() { try { String aspect_scope; String aspect_beforemethod; String aspect_aftermethod; foreach (Aspect_Leaf bean in LTCingFWSet.XmlConfigs.AspectBranch.AspectLeafs) { aspect_scope = bean.Scope; aspect_beforemethod = bean.BeforeMethod; aspect_aftermethod = bean.AfterMethod; FwAopBean aspect = new FwAopBean(aspect_scope, aspect_beforemethod, aspect_aftermethod); LTCingFWSet.Aspects.Add(aspect); } } catch (Exception ex) { throw new LTCingFWException("查找配置文件标注切面出错!", ex); } }
/// <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()); }