/// <summary> /// 组装并返回控制器对应行为的查找关键字 /// </summary> /// <param name="controllerName">控制器名称</param> /// <param name="areaName">区域名称</param> /// <param name="actionUrl">请求URL</param> /// <param name="actionName">控制器行为名称</param> /// <param name="method">可接受的请求方法数组</param> /// <param name="urlAttribute"></param> /// <param name="actionUrlData"></param> /// <param name="methodInfo"></param> /// <param name="globalConfig"></param> /// <param name="plugInfo"></param> /// <returns></returns> public static string[] GetActionKeys(string controllerName, string areaName, out string actionUrl, out string actionName, out string[] method, out UrlAttribute urlAttribute,out NFinal.Url.ActionUrlData actionUrlData, MethodInfo methodInfo, NFinal.Config.Global.GlobalConfig globalConfig, NFinal.Plugs.PlugInfo plugInfo) { string urlPrefix = null; if (plugInfo.urlPrefix?.Length > 0) { urlPrefix = plugInfo.urlPrefix; } List<string> actionKeys = new List<string>(); actionUrlData = null; method = null; urlAttribute = null; actionUrl = plugInfo.config.url.prefix; actionName = null; if (!string.IsNullOrEmpty(areaName)) { actionUrl += "/" + areaName; } if (!string.IsNullOrEmpty(controllerName)) { actionUrl += "/" + controllerName; } bool hasUrlAttribute = false; var attributes = methodInfo.GetCustomAttributes(true); bool hasActionAttribute = false; foreach (var attr in attributes) { var attrType = attr #if (NET40 || NET451 || NET461) .GetType();
//public static Dictionary<string, NFinal.ViewDelegateData> dicViews = new Dictionary<string, NFinal.ViewDelegateData>(); /// <summary> /// 视图执行代理缓存 /// </summary> /// <summary> /// 视图初始化 /// </summary> /// <param name="globalConfig"></param> public static void Init(NFinal.Config.Global.GlobalConfig globalConfig) { NFinal.Plugs.PlugInfo plug = null; Assembly assembly = null; Module[] modules = null; NFinal.ViewDelegateData dele; ViewAttribute viewAttr; NFinal.Collections.FastDictionary <string, ViewDelegateData> viewDataDictionary = new NFinal.Collections.FastDictionary <string, NFinal.ViewDelegateData>(); for (int i = 0; i < NFinal.Plugs.PlugManager.plugInfoList.Count; i++) { plug = NFinal.Plugs.PlugManager.plugInfoList[i]; if (!plug.loadSuccess) { continue; } assembly = plug.assembly; modules = assembly.GetModules(); for (int j = 0; j < modules.Length; j++) { Type[] types = modules[j].GetTypes(); for (int k = 0; k < types.Length; k++) { #if (NET40 || NET451 || NET461) var attrs = types[k].GetCustomAttributes(typeof(ViewAttribute), true); #endif #if NETCORE var attrs = types[k].GetTypeInfo().GetCustomAttributes(typeof(ViewAttribute), false); #endif if (attrs.Count() > 0) { viewAttr = (ViewAttribute)attrs.First(); if (string.IsNullOrEmpty(viewAttr.viewUrl)) { viewAttr.viewUrl = types[k].FullName.Replace('.', '/'); } dele = new ViewDelegateData(); dele.viewTypeHandle = types[k].TypeHandle; dele.renderMethod = null;//GetRenderDelegate(dele.renderMethodInfo); dele.viewClassName = types[k].FullName; //dicViews.Add(viewAttr.viewUrl, dele); if (viewDataDictionary.ContainsKey(viewAttr.viewUrl)) { var oldViewDelegateData = viewDataDictionary[viewAttr.viewUrl]; throw new NFinal.Exceptions.DuplicateViewUrlException(oldViewDelegateData.viewClassName, dele.viewClassName); } else { viewDataDictionary.Add(viewAttr.viewUrl, dele); } } } } } ViewDelegate.viewFastDic = viewDataDictionary; }
/// <summary> /// 加载插件 /// </summary> public static void Init() { if (plugInfoList == null) { if (!NFinal.Config.Configration.isInit) { NFinal.Config.Configration.Init(); } plugInfoList = new List <PlugInfo>(); NFinal.Plugs.Loader.IAssemblyLoader assemblyLoader = new NFinal.Plugs.Loader.AssemblyLoader(); NFinal.Plugs.PlugInfo plugInfo = null; bool loadSuccess = false; string assemblyFilePath = null; foreach (var plug in NFinal.Config.Configration.plugConfigDictionary) { loadSuccess = false; assemblyFilePath = NFinal.IO.Path.GetApplicationPath(plug.Value.plug.assemblyPath); if (File.Exists(assemblyFilePath)) { try { assemblyLoader.Load(assemblyFilePath); loadSuccess = true; } catch (Exception ex) { loadSuccess = false; //throw ex; } } else { throw new NFinal.Exceptions.PlugAssemblyNotFoundException(assemblyFilePath); } plugInfo = new PlugInfo(); if (loadSuccess) { plugInfo.assembly = assemblyLoader.assemblyDictionary[assemblyFilePath]; } else { plugInfo.assembly = null; } plugInfo.loadSuccess = loadSuccess; plugInfo.config = NFinal.Config.Configration.plugConfigDictionary[plug.Value.plug.name]; plugInfo.assemblyFullPath = assemblyFilePath; //plugInfo.configPath = plug.configPath; plugInfo.description = plug.Value.plug.description; plugInfo.enable = plug.Value.plug.enable; plugInfo.name = plug.Value.plug.name; plugInfo.urlPrefix = plug.Value.plug.urlPrefix; plugInfoList.Add(plugInfo); } } }
public static void AddActionDataForMethod<TContext, TRequest>(NFinal.Collections.FastDictionary<string, ActionData<TContext, TRequest>> actionDataDictionary, Dictionary<string, NFinal.Url.FormatData> formatMethodDictionary, Assembly assembly, Type controller, ActionData<TContext, TRequest> actionData, MethodInfo methodInfo,string controllerName,string areaName, NFinal.Config.Global.GlobalConfig globalConfig, NFinal.Plugs.PlugInfo plugInfo) { if (methodInfo.IsAbstract || methodInfo.IsVirtual || methodInfo.IsGenericMethod || methodInfo.IsPrivate||methodInfo.ReturnType!=typeof(void) || methodInfo.IsStatic || methodInfo.IsConstructor) { return; } string actionName; string actionUrl; string[] actionKeys; string[] method; UrlAttribute urlAttribute; NFinal.Url.ActionUrlData actionUrlData; actionKeys = GetActionKeys(controllerName, areaName, out actionUrl, out actionName, out method, out urlAttribute, out actionUrlData, methodInfo, globalConfig, plugInfo); if (urlAttribute == null) { actionData.urlString = null; actionData.contentType = "text/html; charset=utf-8"; actionData.compressMode = CompressMode.None; } else { actionData.urlString = urlAttribute.urlString; actionData.contentType = urlAttribute.contentType; actionData.compressMode = urlAttribute.compressMode; } actionData.className = controller.FullName; actionData.methodName = methodInfo.Name; actionData.actionUrlData = actionUrlData; actionData.controllerName = controllerName; actionData.areaName = areaName; actionData.actionUrl = actionUrl; actionData.actionName = actionName; actionData.method = method; actionData.plugConfig = plugInfo.config; if (actionData.actionUrlData != null) { formatMethodDictionary.Add(methodInfo.Name, new NFinal.Url.FormatData(actionData.actionUrlData.formatUrl, actionData.actionUrlData.actionUrlNames)); } else { formatMethodDictionary.Add(methodInfo.Name, new NFinal.Url.FormatData(actionData.actionUrl, null)); } actionData.IAuthorizationFilters = GetFilters<NFinal.Filter.IAuthorizationFilter>( typeof(NFinal.Filter.IAuthorizationFilter), controller, methodInfo); actionData.IParametersFilters = GetFilters<NFinal.Filter.IParameterFilter>( typeof(NFinal.Filter.IParameterFilter), controller, methodInfo); actionData.IBeforeActionFilters = GetFilters<NFinal.Filter.IBeforeActionFilter>( typeof(NFinal.Filter.IBeforeActionFilter), controller, methodInfo ); actionData.IAfterActionFilters = GetFilters<NFinal.Filter.IAfterActionFilter>( typeof(NFinal.Filter.IAfterActionFilter), controller, methodInfo ); actionData.IResponseFilters = GetFilters<NFinal.Filter.IResponseFilter>( typeof(NFinal.Filter.IResponseFilter), controller, methodInfo); actionData.actionExecute = NFinal.Action.Actuator.GetRunActionDelegate<TContext, TRequest>(assembly, controller, methodInfo,actionData); foreach (var actionKey in actionKeys) { if (actionDataDictionary.ContainsKey(actionKey)) { var oldActionData = actionDataDictionary[actionKey]; throw new NFinal.Exceptions.DuplicateActionUrlException(oldActionData.className, oldActionData.methodName, actionData.className, actionData.methodName); } else { actionDataDictionary.Add(actionKey, actionData); } } }
/// <summary> /// 向全局添加控制器行为信息 /// </summary> /// <typeparam name="TContext">Http请求上下文类型</typeparam> /// <typeparam name="TRequest">Http请求类型</typeparam> /// <param name="actionDataDictionary">控制器行为数据信息字典</param> /// <param name="formatMethodDictionary">控制器行为URl格式化字典</param> /// <param name="assembly">当前程序集</param> /// <param name="controller">控制器类型信息</param> /// <param name="globalConfig">全局配置信息</param> /// <param name="plugInfo">插件信息</param> public static void AddActionData<TContext, TRequest>(NFinal.Collections.FastDictionary<string, ActionData<TContext, TRequest>> actionDataDictionary, Dictionary<string, NFinal.Url.FormatData> formatMethodDictionary, Assembly assembly, Type controller, NFinal.Config.Global.GlobalConfig globalConfig, NFinal.Plugs.PlugInfo plugInfo) { Type viewBagType = null; viewBagType = controller.GetField("ViewBag").FieldType; if (viewBagType == typeof(object)) { MethodInfo[] actions = null; string controllerName; string areaName; ActionData<TContext, TRequest> actionData; GetControllerUrl(out controllerName, out areaName, controller, globalConfig); actions = controller.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public); #if NETCORE //查找函数 var controllerAttributeList = controller.GetTypeInfo().GetCustomAttributes(typeof(NFinal.ActionExportAttribute), true); #else var controllerAttributeList = controller.GetCustomAttributes(typeof(NFinal.ActionExportAttribute), true); #endif MethodInfo action = null; bool hasAction = false; ActionExportAttribute actionExportAttribute = null; foreach (var controllerAttribute in controllerAttributeList) { actionExportAttribute = (NFinal.ActionExportAttribute)controllerAttribute; if (actionExportAttribute.types == null) { action = controller.GetMethod(actionExportAttribute.methodName); } else { action = controller.GetMethod(actionExportAttribute.methodName, actionExportAttribute.types); } if (action == null) { throw new NFinal.Exceptions.NotFoundExportActionException(controller.FullName, actionExportAttribute.methodName); } hasAction = false; foreach (var actionTmp in actions) { if (actionTmp == action) { hasAction = true; } } if (!hasAction) { actionData = new ActionData<TContext, TRequest>(); actionData.viewBagType = actionExportAttribute.viewBagType.TypeHandle; AddActionDataForMethod(actionDataDictionary, formatMethodDictionary, assembly, controller, actionData, action, controllerName, areaName, globalConfig, plugInfo); } } //MethodInfo actionExportList = for (int m = 0; m < actions.Length; m++) { if (actions[m].IsAbstract || actions[m].IsVirtual || actions[m].IsGenericMethod || actions[m].IsPrivate || actions[m].ReturnType != typeof(void) || actions[m].IsStatic || actions[m].IsConstructor) { continue; } actionData = new ActionData<TContext, TRequest>(); string modelTypeName = controller.Namespace + "." + controller.Name + "_Model"; modelTypeName += "." + actions[m].Name; viewBagType = assembly.GetType(modelTypeName); if (viewBagType == null) { throw new NFinal.Exceptions.ModelNotFoundException(modelTypeName); } else { actionData.viewBagType = viewBagType.TypeHandle; } AddActionDataForMethod(actionDataDictionary, formatMethodDictionary, assembly, controller, actionData, actions[m], controllerName, areaName, globalConfig, plugInfo); } } }
/// <summary> /// 控制器行为初始化函数 /// </summary> /// <typeparam name="TContext">Htpp上下文类型</typeparam> /// <typeparam name="TRequest">Http请求信息类型</typeparam> /// <param name="globalConfig">全局配置数据</param> public static void Init<TContext, TRequest>(NFinal.Config.Global.GlobalConfig globalConfig) { Module[] modules = null; Type[] types = null; NFinal.Collections.FastDictionary<string, ActionData<TContext, TRequest>> actionDataDictionary = new NFinal.Collections.FastDictionary<string, ActionData<TContext, TRequest>>(); //List<KeyValuePair<string, ActionData<TContext, TRequest>>> actionDataList = new List<KeyValuePair<string, ActionData<TContext, TRequest>>>(); NFinal.Collections.FastDictionary<RuntimeTypeHandle, Dictionary<string, NFinal.Url.FormatData>> formatControllerDictionary = new NFinal.Collections.FastDictionary<RuntimeTypeHandle, Dictionary<string, NFinal.Url.FormatData>>(); Type controller = null; bool hasExecuteConfigure = false; for (int i = 0; i < NFinal.Plugs.PlugManager.plugInfoList.Count; i++) { hasExecuteConfigure = false; ///////////////////////////////////////////////////////////////////// // //Assembly.Load //精确加载 // // //Assembly.LoadFrom //加载dll的引入 // // //Assembly.LoadFile //仅加载自己 // ///////////////////////////////////////////////////////////////////// NFinal.Plugs.PlugInfo plugInfo = NFinal.Plugs.PlugManager.plugInfoList[i]; if (!plugInfo.loadSuccess || plugInfo.enable==false) { continue; } Assembly assembly = plugInfo.assembly; modules = assembly.GetModules(); for (int j = 0; j < modules.Length; j++) { types = modules[j].GetTypes(); for (int k = 0; k < types.Length; k++) { controller = types[k]; //控制器必须以Controller结尾 if ((!controller.FullName.EndsWith("Controller", StringComparison.Ordinal)) ) { continue; } //该类型继承自IAction并且其泛不是dynamic类型 #if (NET40 || NET451 || NET461) if (typeof(NFinal.Action.IAction<TContext, TRequest>).IsAssignableFrom(controller)) { if (!controller.IsGenericType) #endif #if NETCORE if (typeof(NFinal.Action.IAction<TContext, TRequest>).IsAssignableFrom(controller)) { if (!controller.GetTypeInfo().IsGenericType) #endif { if (!hasExecuteConfigure) { var configureMethodInfo = controller.GetMethod("Configure", BindingFlags.Static | BindingFlags.Public); if (configureMethodInfo != null) { var parameters = configureMethodInfo.GetParameters(); if (parameters.Length == 1 && parameters[0].ParameterType == typeof(NFinal.Config.Plug.PlugConfig)) { configureMethodInfo.Invoke(null, new object[] { plugInfo.config }); hasExecuteConfigure = true; } } } Dictionary<string, NFinal.Url.FormatData> formatMethodDic = new Dictionary<string, NFinal.Url.FormatData>(); AddActionData(actionDataDictionary, formatMethodDic, assembly, controller, globalConfig, plugInfo); formatControllerDictionary.Add(controller.TypeHandle, formatMethodDic); } } } } } //如果未找到任何一个控制器类型,则抛出异常 if (formatControllerDictionary.Count < 1) { throw new NFinal.Exceptions.HasNoControllerInProjectException(); } NFinal.Url.ActionUrlHelper.formatControllerDictionary = formatControllerDictionary; if (globalConfig.debug.enable) { NFinal.Url.ActionUrlHelper.GetUrlRouteJsContent(globalConfig); NFinal.Url.ActionUrlHelper.GenerateActionDebugHtml(globalConfig); } //} //添加图标响应 //Icon.Favicon.Init(actionDataList); Middleware.Middleware<TContext, TRequest>.actionFastDic = new Collections.FastSearch.FastSearch<ActionData<TContext, TRequest>>(actionDataDictionary); actionDataDictionary.Clear(); }