上面的CacheMethodInfo是用于缓存调用方法的相关信息的,第一篇我们有提到过优化缓存的一些方法,其中就包括缓存+委托。但这里我们并不直接缓存方法的MethodInfo,因为缓存MethodInfo的话,需要通过Invoke去执行,这样的效率比较低。这里我缓存的是方法的委托,该委托的签名为:Func<object, object[], object>,该委托的返回值为object类型,表示可以返回任意的类型(我们可以在组件内部进行处理,例如如果是引用类型(非string),就将其序列化为json,但这里并没有实现)。该委托接收两个参数,第一个参数是方法所属的对象,如果是静态方法就是null;第二个参数是方法的参数,定义为object[]表示可以接收任意类型的参数。通过委托执行方法,与直接调用方法的效率差别就不是很大(对委托不熟悉的朋友可以参见:委托)。CacheMethodInfo的定义如下:
/// <summary>
/// 缓存方法信息
/// </summary>
sealed class CacheMethodInfo
{
/// <summary>
/// 方法名称
/// </summary>
public string MethodName { get; set; }
/// <summary>
/// 方法委托
/// </summary>
public Func<object, object[], object> Func { get; set; }
/// <summary>
/// 方法参数
/// </summary>
public ParameterInfo[] Parameters { get; set; }
/// <summary>
/// Ajax标记属性
/// </summary>
public AjaxMethodAttribute AjaxMethodAttribute { get; set; }
}
核心方法
1. Eexcutor.GetDelegateInfo 获取方法相关信息
该方法用于遍历页面类,获取所有AjaxMethodAttribute标记的方法信息,生成一个CacheMethodInfo对象,包括标记信息、方法名称、参数信息,以及最重要的方法委托。该对象会缓存在一个哈希表中,下次获取时,直接从内存获得。
/// <summary>
/// 获取页面标记方法信息
/// </summary>
/// <param name="page">页面对象</param>
/// <param name="methodName">方法名称</param>
internal static CacheMethodInfo GetDelegateInfo(Page page, string methodName)
{
if (page == null)
{
throw new ArgumentNullException("page");
}
Type type = page.GetType();
//ajaxDelegateTable是一个Hashtable
Dictionary<string, CacheMethodInfo> dic = ajaxDelegateTable[type.AssemblyQualifiedName] as Dictionary<string, CacheMethodInfo>;
if (dic == null)
{
dic = new Dictionary<string, CacheMethodInfo>();
//遍历页面的所有MethodInfo
IEnumerable<CacheMethodInfo> infos = (from m in type.GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static)
let ca = m.GetCustomAttributes(typeof(AjaxMethodAttribute), false).FirstOrDefault()
where ca != null
select new CacheMethodInfo
{
//方法标记属性
AjaxMethodAttribute = ca as AjaxMethodAttribute,
//方法名称
MethodName = m.Name,
//方法参数信息
Parameters = m.GetParameters()
});
if (infos.IsNullOrEmpty())
{
return null;
}
for (int i = 0, length = infos.Count(); i < length; i++)
{
CacheMethodInfo cacheMethodInfo = infos.ElementAt(i);
string name = cacheMethodInfo.MethodName;
MethodInfo methodInfo = type.GetMethod(name);
if (!dic.ContainsKey(name))
{
//根据MethodInfo获取方法委托
cacheMethodInfo.Func = ReflectionUtil.GetMethodDelegate(methodInfo);
dic.Add(name, cacheMethodInfo);
}
}
ajaxDelegateTable[type.AssemblyQualifiedName] = dic;
}
CacheMethodInfo currentMethodInfo = null;
dic.TryGetValue(methodName, out currentMethodInfo);
return currentMethodInfo;
}









