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());
}
}
}
这样我们所有需要调用的行业应用模块全载入内存,为后续的调用做好准备,下期将继续介绍行业模块函数的执行过程
请先 后发表评论~