ASP.NET原创框架二

接着上集框架实现几大接口

IHttpModule应用接口Init函数实现框架的初始工作

static public void InitEngine(HttpContext context)

{

...

m_CoreEngine.InitCoreEngine(context);

...

}

IHttpHandlerFactory 实现不同后缀访问的拦截,目前支持后缀有.aspx页面 .ajax的ajax访问 .jsonp的跨域访问 .api供第三方调用接口 .p2p平台之间互调 .do ajax耗时调用接口 .app手机客户端访问接口

.aspx页面IHttpHandlerFactory接口的实现

public sealed class XNPageHandlerFactory : IHttpHandlerFactory{

private AspnetPageHandlerFactory _msPageHandlerFactory;

IHttpHandler IHttpHandlerFactory.GetHandler(HttpContext context,

string requestType, string virtualPath, string physicalPath)

{

if(XNWebApplication.bWebAPI)

{

if (_msPageHandlerFactory == null)

_msPageHandlerFactory = new AspnetPageHandlerFactory();

// 调用ASP.NET默认的Page处理器工厂来处理


return _msPageHandlerFactory.GetHandler(context, requestType, virtualPath, physicalPath);

}

// 尝试根据请求路径获取Action

InvokeInfo vkInfo = XNWebApplication.GetJsonModeEngine(context).GetPageActionInvokeInfo(context,virtualPath);

// 如果没有找到合适的Action,并且请求的是一个ASPX页面,则按ASP.NET默认的方式来继续处理

if (vkInfo == null && virtualPath.EndsWith(".aspx", StringComparison.OrdinalIgnoreCase))

{

try

{

if (vkInfo == null)

{

string FName = context.Request.PhysicalApplicationPath + "//template//page404.html";

string str = File.ReadAllText(FName);

context.Response.Write(str);

context.Response.End();

return null;

}

if (_msPageHandlerFactory == null)

_msPageHandlerFactory = new AspnetPageHandlerFactory();

// 调用ASP.NET默认的Page处理器工厂来处理

return _msPageHandlerFactory.GetHandler(context, requestType, virtualPath, physicalPath);

}

catch (Exception e)

{

return null;

}

}

return ActionPageHandler.CreateHandler(vkInfo);

}

}

IHttpHandler

具体处理各类后缀的实现

internal class ActionPageHandler : IHttpHandler

{

internal InvokeInfo InvokeInfo;

public void ProcessRequest(HttpContext context)

{

// 调用核心的工具类,执行Action最终通过

XNWebApplication.GetJsonModeEngine().ExePageAction(context, this.InvokeInfo);

}

public bool IsReusable

{

get { return false; }

}

public static ActionPageHandler CreateHandler(InvokeInfo vkInfo)

{

SessionMode mode = vkInfo.GetSessionMode();


if (mode == SessionMode.NotSupport)

return new ActionPageHandler { InvokeInfo = vkInfo };

else if (mode == SessionMode.ReadOnly)

return new ReadOnlySessionActionPageHandler { InvokeInfo = vkInfo };

else

return new RequiresSessionActionPageHandler { InvokeInfo = vkInfo };

}

}

关于路由地址,相应的IHttpHandlerFactory通过XNWebApplication.GetJsonModeEngine(context)获得核心接口,然后通过核心接口函数GetPageActionInvokeInfo获得GetAjaxActionInvokeInfo 获得相应访问路由信息InvokeInfo

其中InvokeInfo类定义

namespace XNWebEngine

{

public class InvokeInfo

{

public bool bCache;

public bool bCanBind;

public bool bCanClient;//是否客户端调用

public bool bCanCrossDomain;//是否支持跨域

public bool bCanEnable;//是否可用

public bool bCanGet;//是否可get调用

public bool bCanNoLogin;//是否支持未登陆调用

public bool bCanP2P;//是否可P2P调用

public bool bCanPost;//是否可post调用

public bool bCanThird;//是否可第三方调用

public bool bCanW2W;

public bool bHaveMode;

public bool bHTML;

public bool bPoolWait;

public string ClassFullName;//类名

public Hashtable FunctionAttrHash;//函数属性描述

public string FunctionName;//类函数

public string HTMLPath;

public bool isAppFunction;//是否应用函数

public bool isEncFunction;//是否加密函数

public Type m_RealType;///处在真实的类型

public string ModeServer;

public string ServerUrl;

public InvokeInfo();

public Type GetRunType();

public SessionMode GetSessionMode();

public void SetRunType(Type tt);

public void SetSessionMode(SessionMode m);

}

}

如:/CoreSYS.SYS/hello.aspx

解析返回的invokeInfo典型参数值ClassFullName为CoreSYS.SYS 其中CoreSYS为命名空间 SYS为具体类 FunctionName为:hello,也就是说访问命名空间为CoreSYS下的类SYS下的函数hello

为能动态访问类和函数,框架采用反射方式加载所需的类,实现动态调用

为实现统一的类函数访问,特定义应用基类,编写不同的应用可派生此类实现自己的需要,如CoreSYS.SYS也派生于此类见

namespace CoreSYS

{

public partial class SYS : BaseJsonMode

{..

}

}

派生于BaseJsonMode的类也就是我们通过各类后缀访问的类函数,该基类实现基本开发需求的函数,如身份认证 页面渲染 Redis缓存 MSMQ消息 MQTT事件 任务调度 分布式库访问 Cookie操作 模块互调等,后续将有文章详细介绍基类BaseJsonMode的实现

现在介绍核心框架的初始化主要完成工作

public bool InitCoreEngine(HttpContext ctx,string web=""){

//分布式数据库的初始化工作

//缓存消息事件角色权限加载等初始化工作

//ws服务初始化

//应用模块的加载

}

关于应用模块的记载

所有的应用模块位于ASP.NET应用下的JsonMode目录下

可以看到JsonMode目录下有很多子目录,该子目录便是我们实现的应用,里面特殊目录sharedll为个模块共享功能dll,已代码工厂应用模块为例里面文件如下

其中CodeFactory.dll为主应用模块 CodeFactory_1_base.dll CodeFactory_0_base.dll为代码工厂实现的基类,根据扩展需要可以自写CodeFactory_2_base.dll等view为模块的视文件目录里面包含所应用的UI模块语言等

这些模块的加载配置在web.config里定义如下

<probing privatePath="JsonMode/前沿模块;JsonMode/ShareDll;JsonMode/动态表模块;JsonMode/核心模块;JsonMode/代码工厂;..../>

//加载所有行业模块

public void LoadMode()

{

。。。

BaseJsonMode.BasePath = BasePath;

BaseJsonMode.m_JsonModeEngine = this;

BaseJsonMode.m_ICoreInterFace = this;

BaseJsonMode.InitLock();

LoadTableClass();

ArrayList m_ModePathArray;

m_ServerInfoST.m_ClassArray = new ArrayList();

m_ServerInfoST.m_LocalBaseArray = new ArrayList();

m_ServerInfoST.m_TradeArray = GetTradeArray();

GetJsonMode(out m_ModePathArray);

int i = 0;

for (i = 0; i < m_ModePathArray.Count; i++)

{

DirectoryInfo TheFolder = (DirectoryInfo)m_ModePathArray[i];

ArrayList m_OneModeClassArray = null;

if (TheFolder.Name != "shareDll" && TheFolder.Name != "核心模块")

{

m_OneModeClassArray = new ArrayList();

m_ModeApplicationClassHash.Add(TheFolder.Name, m_OneModeClassArray);

m_JsonModeApplicationArray.Add(TheFolder.Name);

}

WriteAppLOG("开始载入:" + TheFolder);

LoadOneJsonMode(TheFolder, m_OneModeClassArray);

WriteAppLOG("载入完毕:" + TheFolder);

}

。。。

}

//加载一个行业模块

public void LoadOneJsonMode(DirectoryInfo TheFolder, ArrayList m_OneModeClassArray)

{

string filename = "";

string ModeName = TheFolder.Name;

string sRealModeName = ModeName.ToLower();

if (sRealModeName == "sharedll")

{

LoadDataModel(TheFolder);

return;

}

List<FileInfo> m_FileInfoList=PaiXuJsonMode(TheFolder);

//foreach (FileInfo NextFile in TheFolder.GetFiles())

for (int mm = 0; mm < m_FileInfoList.Count;mm++ )

{

FileInfo NextFile = m_FileInfoList[mm];

string rawfilename;

filename = NextFile.Name;

rawfilename = filename;

if (filename.IndexOf(".dll") == -1)

continue;

if (filename.IndexOf("_base.dll") != -1)

{

continue;

}

filename = TheFolder.FullName + "\\" + filename;

ArrayList m_TObjList = new ArrayList();

try

{

Assembly assembly = null;

assembly = Assembly.LoadFrom(filename);

List<Type> m_BaseTypeList = new List<Type>();

foreach (Type t in assembly.GetTypes())

{

try

{

BaseJsonMode.BasePath = BasePath;

}

catch (System.Exception e)

{

}

Type m_TT = t;

bool bAdd = false;

while (true)

{

try

{

if (m_TT.BaseType.FullName != "System.Object")

{

if (m_TT.BaseType.FullName.IndexOf("_base") != -1)

{

m_BaseTypeList.Add(m_TT.BaseType);

}

if (m_TT.BaseType.FullName.IndexOf("JsonMode") != -1)

{

bAdd = true;

break;

}

else

m_TT = m_TT.BaseType;

}

else

break;

}

catch

{

bAdd = false;

break;

}

}

if (bAdd)

{

if (m_OneModeClassArray != null)

m_OneModeClassArray.Add(t.FullName);

m_TObjList.Add(t);

if (m_ClassNameToRealName.ContainsKey(t.FullName.ToLower()))

{

}

else

{

m_ClassNameToRealName.Add(t.FullName.ToLower(), t.FullName);

}

Hashtable m_OneApplication = new Hashtable();

if (t.FullName.IndexOf("Newtonsoft.") == -1)

m_GlobalApplication.Add(t.FullName, m_OneApplication);

}

}

Type[] m_ObjList = new Type[m_TObjList.Count];

OneMode m_OneMode = new OneMode();

int nIndex = TheFolder.FullName.IndexOf(BasePath);

if (nIndex != -1)

{

string sModePath = TheFolder.FullName.Substring(BasePath.Length, TheFolder.FullName.Length - BasePath.Length);

m_OneMode.m_ModePath = sModePath;

}

int nCnt = m_TObjList.Count;

m_OneMode.m_JsonModeInfoArray = new OneJsonModeInfo[nCnt];

int i = 0;

for (i = 0; i < nCnt; i++)

{

m_ObjList[i] = (Type)m_TObjList[i];

string Name = ((Type)m_TObjList[i]).FullName;

if (!m_FullClassTypes.Contains(Name))

{

OneFullClassInfo m_OneFullClassInfo = new OneFullClassInfo();

m_OneFullClassInfo.ModePath = m_OneMode.m_ModePath;

m_OneFullClassInfo.filename = rawfilename;

m_OneFullClassInfo.t = m_ObjList[i];

m_OneFullClassInfo.ModeName = ModeName;

m_OneFullClassInfo.m_MethodInfos = Hashtable.Synchronized(new Hashtable());

m_OneFullClassInfo.m_FastDeletgates = Hashtable.Synchronized(new Hashtable());

m_OneFullClassInfo.m_InvokeInfos = Hashtable.Synchronized(new Hashtable());

m_FullClassTypes.Add(Name, m_OneFullClassInfo);

m_ServerInfoST.m_ClassArray.Add(Name);

}

if (!m_ModeShareClassTypes.Contains(Name))

{

OneFullClassInfo m_OneFullClassInfo = new OneFullClassInfo();

m_OneFullClassInfo.ModePath = m_OneMode.m_ModePath;

m_OneFullClassInfo.filename = rawfilename;

m_OneFullClassInfo.t = m_ObjList[i];

m_OneFullClassInfo.ModeName = ModeName;

m_OneFullClassInfo.m_MethodInfos = Hashtable.Synchronized(new Hashtable());

m_OneFullClassInfo.m_FastDeletgates = Hashtable.Synchronized(new Hashtable());

m_OneFullClassInfo.m_InvokeInfos = Hashtable.Synchronized(new Hashtable());

m_ModeShareClassTypes.Add(Name, m_OneFullClassInfo);

}

MethodInfo TMethod;

Type m_T;

if (GetFunction(m_ObjList[i], "SetEngineInterface", out m_T))

{

m_T.InvokeMember("SetEngineInterface",

BindingFlags.DeclaredOnly |

BindingFlags.Public |

BindingFlags.Static | BindingFlags.InvokeMethod,

null,

null,

new Object[] { this });

}

if (GetFunction(m_ObjList[i], "SetCoreInterface", out m_T))

{

m_T.InvokeMember("SetCoreInterface",

BindingFlags.DeclaredOnly |

BindingFlags.Public |

BindingFlags.Static | BindingFlags.InvokeMethod,

null,

null,

new Object[] { this });

}

if (GetFunction(m_ObjList[i], "SetModeInfo", out m_T))

{

m_T.InvokeMember("SetModeInfo",

BindingFlags.DeclaredOnly |

BindingFlags.Public |

BindingFlags.Static | BindingFlags.InvokeMethod,

null,

null,

new Object[] { BasePath });

}

if (i == 0)

{

if (m_BaseTypeList.Count > 0)

{

for (int k = 0; k < m_BaseTypeList.Count; k++)

{

if (GetFunction(m_BaseTypeList[k], "SetJsonMode", out m_T))

{

m_T.InvokeMember("SetJsonMode",

BindingFlags.DeclaredOnly |

BindingFlags.Public |

BindingFlags.Static | BindingFlags.InvokeMethod,

null,

null,

new Object[] { m_OneMode.m_ModePath, m_ObjList[i].FullName });

}

}

}

}

if (GetFunction(m_ObjList[i], "SetJsonMode", out m_T))

{

m_T.InvokeMember("SetJsonMode",

BindingFlags.DeclaredOnly |

BindingFlags.Public |

BindingFlags.Static | BindingFlags.InvokeMethod,

null,

null,

new Object[] { m_OneMode.m_ModePath, m_ObjList[i].FullName });

}

if (!GetFunction(m_ObjList[i], "GetModeInfos", out m_T))

{

m_OneMode.m_JsonModeInfoArray[i] = null;

}

else

{

m_OneMode.m_JsonModeInfoArray[i] = m_T.InvokeMember("GetModeInfos",

BindingFlags.DeclaredOnly |

BindingFlags.Public |

BindingFlags.Static | BindingFlags.InvokeMethod,

null,

null,

new Object[] { }) as OneJsonModeInfo;

if (m_OneMode.m_JsonModeInfoArray[i] == null)

{

m_OneMode.m_JsonModeInfoArray[i] = new OneJsonModeInfo();

m_OneMode.m_JsonModeInfoArray[i].m_EventInfoArray = new ArrayList();

m_OneMode.m_JsonModeInfoArray[i].m_EventNameArray = new ArrayList();

m_OneMode.m_JsonModeInfoArray[i].m_FunctionInfoArray = new ArrayList();

m_OneMode.m_JsonModeInfoArray[i].m_FunctionNameArray = new ArrayList();

}

}

}

m_OneMode.filename = rawfilename;

m_OneMode.m_TypeArray = m_ObjList;

m_ModeTypeArray.Add(m_OneMode);

}

catch (System.Exception e)

{

CoreEngine.WriteErrorLOG("LoadOneJsonMode(" + TheFolder.Name + ")失败:" + e.ToString());

}

}

}

这样我们所有需要调用的行业应用模块全载入内存,为后续的调用做好准备,下期将继续介绍行业模块函数的执行过程

举报
评论 0