上传文件至「/」

This commit is contained in:
2026-08-27 11:45:35 +08:00
commit 96b8361605
4 changed files with 1957 additions and 0 deletions
+943
View File
@@ -0,0 +1,943 @@
using System;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Reflection;
using System.Text;
using System.Xml.XPath;
using GThinking.N_MISPROAS.Web.AjaxServices;
using GThinking.N_MISPRO.Data;
namespace GThinking.S_XLXSBJ
{
/// <summary>
/// 服务方法管理相关服务。
/// </summary>
public class ServiceMethod
{
/// <summary>
/// 根据传入的 DLL 文件地址,反射获取其中标记了 AjaxMethod 的服务方法信息,
/// 并写入数据库表:SRCMD、SRCMETHOD、SRCMETHODPARAMS、SRCTYPE、SRCPROP。
/// </summary>
/// <param name="filePath">DLL 文件地址。</param>
/// <returns>操作结果。</returns>
[AjaxMethod(AuthRequried = false)]
public static Dictionary<string, object> SaveServiceMethodInfo(string filePath)
{
Dictionary<string, object> result = new Dictionary<string, object>();
TDatabase dberp = null;
if (string.IsNullOrEmpty(filePath) || !File.Exists(filePath))
{
result["success"] = false;
result["msg"] = "文件地址不能为空或文件不存在";
return result;
}
try
{
dberp = TContextDatabases.GetDatabase("DBERP");
dberp.BeginTrans();
Assembly assembly = Assembly.LoadFrom(filePath);
string macId = Truncate(assembly.GetName().Name, 20);
// 先删除该部件旧数据
DeleteOldModuleData(dberp, macId);
XmlDocHelper xmlDoc = new XmlDocHelper(filePath);
int mdIndex = 0;
Dictionary<string, string> visitedTypes = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
Type[] types = null;
try
{
types = assembly.GetTypes();
}
catch (ReflectionTypeLoadException ex)
{
types = ex.Types;
}
if (types == null)
{
dberp.CommitTrans();
result["success"] = true;
result["msg"] = "未找到可扫描的类型";
result["macId"] = macId;
return result;
}
foreach (Type type in types)
{
if (type == null)
continue;
if (!type.IsClass)
continue;
Dictionary<string, ServiceMethodInfo> methods = GetServiceMethods(type);
if (methods == null || methods.Count == 0)
continue;
mdIndex++;
double mdId = (double)mdIndex;
InsertSRCMD(dberp, macId, mdId, Truncate(type.FullName, 40));
foreach (ServiceMethodInfo smi in methods.Values)
{
string methodDesc = xmlDoc.GetMethodSummary(smi.MethodInfo);
string retDesc = xmlDoc.GetMethodReturns(smi.MethodInfo);
InsertSRCMETHOD(
dberp,
macId,
mdId,
Truncate(smi.MethodName, 32),
Truncate(GetMethodModifiers(smi.MethodInfo), 80),
smi.AuthRequried ? "Y" : "N",
smi.UseHttpGet ? "Y" : "N",
Truncate(methodDesc, 4000),
Truncate(GetTypeDisplayName(smi.ReturnType), 80),
Truncate(retDesc, 1000));
if (smi.ParameterList != null)
{
int paramXh = 0;
foreach (ServiceParameterInfo spi in smi.ParameterList)
{
string paramDesc = xmlDoc.GetParameterSummary(smi.MethodInfo, spi.Name);
InsertSRCMETHODPARAMS(
dberp,
macId,
mdId,
Truncate(smi.MethodName, 32),
(double)paramXh,
Truncate(spi.Name, 32),
Truncate(GetTypeDisplayName(spi.ParameterType), 80),
Truncate(paramDesc, 1000));
ReflectType(spi.ParameterType, dberp, visitedTypes, xmlDoc);
paramXh++;
}
}
ReflectType(smi.ReturnType, dberp, visitedTypes, xmlDoc);
}
}
dberp.CommitTrans();
result["success"] = true;
result["msg"] = "扫描完成";
result["macId"] = macId;
}
catch (Exception ex)
{
if (dberp != null && dberp.InTransaction)
dberp.RollbackTrans();
result["success"] = false;
result["msg"] = ex.Message;
}
return result;
}
/// <summary>
/// 根据 MACID 查询已扫描的服务方法数据。
/// </summary>
/// <param name="macId">服务部件ID(程序集名称)。</param>
/// <returns>包含各表数据的结果。</returns>
[AjaxMethod(AuthRequried = false)]
public static Dictionary<string, object> GetServiceMethodData(string macId)
{
Dictionary<string, object> result = new Dictionary<string, object>();
TDatabase dberp = null;
try
{
dberp = TContextDatabases.GetDatabase("DBERP");
result["SRCMD"] = QueryTableByMacId(dberp, "SRCMD", macId);
result["SRCMETHOD"] = QueryTableByMacId(dberp, "SRCMETHOD", macId);
result["SRCMETHODPARAMS"] = QueryTableByMacId(dberp, "SRCMETHODPARAMS", macId);
result["SRCTYPE"] = QueryAll(dberp, "SRCTYPE");
result["SRCPROP"] = QueryAll(dberp, "SRCPROP");
result["success"] = true;
result["msg"] = "";
}
catch (Exception ex)
{
result["success"] = false;
result["msg"] = ex.Message;
}
return result;
}
#region 数据库操作
private static void DeleteOldModuleData(TDatabase dberp, string macId)
{
string[] tables = new string[] { "SRCMETHODPARAMS", "SRCMETHOD", "SRCMD" };
TSQL sql = new TSQL(dberp);
foreach (string table in tables)
{
sql.Clear();
sql.Add("delete from " + table + " where MACID=:pMACID");
sql.ParamByName("pMACID").Value = macId;
dberp.ExecSQL(sql);
}
}
private static void DeleteTypeData(TDatabase dberp, string typeFullName)
{
TSQL sql = new TSQL(dberp);
sql.Clear();
sql.Add("delete from SRCPROP where TYPEFULLNAME=:pTYPEFULLNAME");
sql.ParamByName("pTYPEFULLNAME").Value = typeFullName;
dberp.ExecSQL(sql);
sql.Clear();
sql.Add("delete from SRCTYPE where TYPEFULLNAME=:pTYPEFULLNAME");
sql.ParamByName("pTYPEFULLNAME").Value = typeFullName;
dberp.ExecSQL(sql);
}
private static List<Dictionary<string, object>> QueryTableByMacId(TDatabase dberp, string tableName, string macId)
{
TSQL sql = new TSQL(dberp);
sql.Add("select " + GetTableColumns(tableName) + " from " + tableName + " where MACID=:pMACID");
sql.ParamByName("pMACID").Value = macId;
DataSet ds = dberp.OpenDataSet(sql);
return DataTableToList(ds.Tables[0]);
}
private static List<Dictionary<string, object>> QueryAll(TDatabase dberp, string tableName)
{
TSQL sql = new TSQL(dberp);
sql.Add("select " + GetTableColumns(tableName) + " from " + tableName);
DataSet ds = dberp.OpenDataSet(sql);
return DataTableToList(ds.Tables[0]);
}
private static string GetTableColumns(string tableName)
{
switch (tableName)
{
case "SRCMD":
return "MACID, MDID, MDNAME";
case "SRCMETHOD":
return "MACID, MDID, METHODNAME, MODIFIERS, AUTHREQUIRED, USEHTTPGET, METHODDESC, RETTYPE, RETDESC";
case "SRCMETHODPARAMS":
return "MACID, MDID, METHODNAME, PARAMXH, PARAMNAME, PARAMTYPE, PARAMDESC";
case "SRCTYPE":
return "TYPEFULLNAME, NAMESPACE, TYPENAME, TYPEDESC";
case "SRCPROP":
return "TYPEFULLNAME, PROPNAME, PROPTYPEFULLNAME, NAMESPACE, PROPTYPE, PROPDESC";
default:
return "*";
}
}
private static List<Dictionary<string, object>> DataTableToList(DataTable dt)
{
List<Dictionary<string, object>> list = new List<Dictionary<string, object>>();
foreach (DataRow row in dt.Rows)
{
Dictionary<string, object> item = new Dictionary<string, object>();
foreach (DataColumn col in dt.Columns)
{
object val = row[col];
item[col.ColumnName] = val == DBNull.Value ? null : val;
}
list.Add(item);
}
return list;
}
private static void InsertSRCMD(TDatabase dberp, string macId, double mdId, string mdName)
{
TSQL sql = new TSQL(dberp);
sql.Clear();
sql.Add("insert into SRCMD(MACID, MDID, MDNAME) values(:pMACID, :pMDID, :pMDNAME)");
sql.ParamByName("pMACID").Value = macId;
sql.ParamByName("pMDID").Value = mdId;
sql.ParamByName("pMDNAME").Value = mdName;
dberp.ExecSQL(sql);
}
private static void InsertSRCMETHOD(TDatabase dberp, string macId, double mdId, string methodName,
string modifiers, string authRequired, string useHttpGet, string methodDesc,
string retType, string retDesc)
{
TSQL sql = new TSQL(dberp);
sql.Clear();
sql.Add("insert into SRCMETHOD(MACID, MDID, METHODNAME, MODIFIERS, AUTHREQUIRED, USEHTTPGET, METHODDESC, RETTYPE, RETDESC) ");
sql.Add("values(:pMACID, :pMDID, :pMETHODNAME, :pMODIFIERS, :pAUTHREQUIRED, :pUSEHTTPGET, :pMETHODDESC, :pRETTYPE, :pRETDESC)");
sql.ParamByName("pMACID").Value = macId;
sql.ParamByName("pMDID").Value = mdId;
sql.ParamByName("pMETHODNAME").Value = methodName;
sql.ParamByName("pMODIFIERS").Value = modifiers;
sql.ParamByName("pAUTHREQUIRED").Value = authRequired;
sql.ParamByName("pUSEHTTPGET").Value = useHttpGet;
sql.ParamByName("pMETHODDESC").Value = methodDesc;
sql.ParamByName("pRETTYPE").Value = retType;
sql.ParamByName("pRETDESC").Value = retDesc;
dberp.ExecSQL(sql);
}
private static void InsertSRCMETHODPARAMS(TDatabase dberp, string macId, double mdId, string methodName,
double paramXh, string paramName, string paramType, string paramDesc)
{
TSQL sql = new TSQL(dberp);
sql.Clear();
sql.Add("insert into SRCMETHODPARAMS(MACID, MDID, METHODNAME, PARAMXH, PARAMNAME, PARAMTYPE, PARAMDESC) ");
sql.Add("values(:pMACID, :pMDID, :pMETHODNAME, :pPARAMXH, :pPARAMNAME, :pPARAMTYPE, :pPARAMDESC)");
sql.ParamByName("pMACID").Value = macId;
sql.ParamByName("pMDID").Value = mdId;
sql.ParamByName("pMETHODNAME").Value = methodName;
sql.ParamByName("pPARAMXH").Value = paramXh;
sql.ParamByName("pPARAMNAME").Value = paramName;
sql.ParamByName("pPARAMTYPE").Value = paramType;
sql.ParamByName("pPARAMDESC").Value = paramDesc;
dberp.ExecSQL(sql);
}
private static void InsertSRCTYPE(TDatabase dberp, string typeFullName, string nameSpace,
string typeName, string typeDesc)
{
TSQL sql = new TSQL(dberp);
sql.Clear();
sql.Add("insert into SRCTYPE(TYPEFULLNAME, NAMESPACE, TYPENAME, TYPEDESC) ");
sql.Add("values(:pTYPEFULLNAME, :pNAMESPACE, :pTYPENAME, :pTYPEDESC)");
sql.ParamByName("pTYPEFULLNAME").Value = typeFullName;
sql.ParamByName("pNAMESPACE").Value = nameSpace;
sql.ParamByName("pTYPENAME").Value = typeName;
sql.ParamByName("pTYPEDESC").Value = typeDesc;
dberp.ExecSQL(sql);
}
private static void InsertSRCPROP(TDatabase dberp, string typeFullName, string propName,
string propTypeFullName, string nameSpace, string propType, string propDesc)
{
TSQL sql = new TSQL(dberp);
sql.Clear();
sql.Add("insert into SRCPROP(TYPEFULLNAME, PROPNAME, PROPTYPEFULLNAME, NAMESPACE, PROPTYPE, PROPDESC) ");
sql.Add("values(:pTYPEFULLNAME, :pPROPNAME, :pPROPTYPEFULLNAME, :pNAMESPACE, :pPROPTYPE, :pPROPDESC)");
sql.ParamByName("pTYPEFULLNAME").Value = typeFullName;
sql.ParamByName("pPROPNAME").Value = propName;
sql.ParamByName("pPROPTYPEFULLNAME").Value = propTypeFullName;
sql.ParamByName("pNAMESPACE").Value = nameSpace;
sql.ParamByName("pPROPTYPE").Value = propType;
sql.ParamByName("pPROPDESC").Value = propDesc;
dberp.ExecSQL(sql);
}
#endregion
#region 反射与类型辅助
private static Dictionary<string, ServiceMethodInfo> GetServiceMethods(Type classType)
{
if (classType == null)
return null;
List<Type> typeList = new List<Type>();
Type current = classType;
typeList.Add(current);
while (current.BaseType != null)
{
current = current.BaseType;
if (current != typeof(object))
typeList.Add(current);
}
Dictionary<string, ServiceMethodInfo> methods = new Dictionary<string, ServiceMethodInfo>(StringComparer.OrdinalIgnoreCase);
BindingFlags flags = BindingFlags.Public | BindingFlags.DeclaredOnly |
BindingFlags.Static | BindingFlags.Instance;
for (int i = typeList.Count - 1; i >= 0; --i)
{
MethodInfo[] methodInfos = typeList[i].GetMethods(flags);
foreach (MethodInfo method in methodInfos)
{
object[] attribs = method.GetCustomAttributes(typeof(AjaxMethodAttribute), true);
if (attribs.Length > 0)
{
AjaxMethodAttribute ajaxAttr = (AjaxMethodAttribute)attribs[0];
ServiceMethodInfo smi = new ServiceMethodInfo(method, ajaxAttr);
smi.LoadMethodParameters();
methods[smi.MethodName] = smi;
}
}
}
return methods;
}
private static string GetMethodModifiers(MethodInfo method)
{
StringBuilder sb = new StringBuilder();
if (method.IsPublic)
sb.Append("public ");
else if (method.IsPrivate)
sb.Append("private ");
else if (method.IsFamily)
sb.Append("protected ");
else if (method.IsAssembly)
sb.Append("internal ");
if (method.IsStatic)
sb.Append("static ");
return sb.ToString().Trim();
}
private static void ReflectType(Type type, TDatabase dberp,
Dictionary<string, string> visitedTypes, XmlDocHelper xmlDoc)
{
if (type == null)
return;
if (type.IsByRef || type.IsPointer)
{
ReflectType(type.GetElementType(), dberp, visitedTypes, xmlDoc);
return;
}
if (type.IsArray)
{
ReflectType(type.GetElementType(), dberp, visitedTypes, xmlDoc);
return;
}
Type underlying = Nullable.GetUnderlyingType(type);
if (underlying != null)
{
ReflectType(underlying, dberp, visitedTypes, xmlDoc);
return;
}
if (type.IsGenericType)
{
Type[] args = type.GetGenericArguments();
foreach (Type arg in args)
ReflectType(arg, dberp, visitedTypes, xmlDoc);
Type def = type.GetGenericTypeDefinition();
if (!IsCustomType(def))
return;
type = def;
}
if (!IsCustomType(type))
return;
string key = type.FullName;
if (string.IsNullOrEmpty(key))
return;
if (visitedTypes.ContainsKey(key))
return;
visitedTypes[key] = key;
string typeFullName = type.FullName.Replace('+', '.');
// 先清理该类型旧数据,再重新写入
DeleteTypeData(dberp, typeFullName);
InsertSRCTYPE(
dberp,
Truncate(typeFullName, 80),
Truncate(type.Namespace, 80),
Truncate(GetTypeShortName(type), 80),
Truncate(xmlDoc.GetSummary(type), 1000));
List<MemberInfo> members = new List<MemberInfo>();
members.AddRange(type.GetProperties(BindingFlags.Public | BindingFlags.Instance));
members.AddRange(type.GetFields(BindingFlags.Public | BindingFlags.Instance));
members.Sort(new MemberNameComparer());
foreach (MemberInfo mi in members)
{
Type memberType = null;
if (mi is PropertyInfo)
memberType = ((PropertyInfo)mi).PropertyType;
else if (mi is FieldInfo)
memberType = ((FieldInfo)mi).FieldType;
else
continue;
string propTypeFullName = memberType.FullName == null ? memberType.Name : memberType.FullName.Replace('+', '.');
InsertSRCPROP(
dberp,
Truncate(typeFullName, 80),
Truncate(mi.Name, 32),
Truncate(propTypeFullName, 80),
Truncate(memberType.Namespace, 80),
Truncate(GetTypeDisplayName(memberType), 80),
Truncate(xmlDoc.GetSummary(mi), 250));
ReflectType(memberType, dberp, visitedTypes, xmlDoc);
}
}
private static bool IsCustomType(Type type)
{
if (type == null)
return false;
if (type.IsGenericParameter)
return false;
if (type.IsPrimitive)
return false;
if (type == typeof(string) || type == typeof(object) || type == typeof(decimal)
|| type == typeof(DateTime) || type == typeof(TimeSpan) || type == typeof(Guid))
return false;
if (type.Namespace != null &&
(type.Namespace.StartsWith("System") || type.Namespace.StartsWith("Microsoft")))
return false;
return true;
}
private static string GetTypeDisplayName(Type type)
{
if (type == null)
return "";
if (type.IsByRef)
return GetTypeDisplayName(type.GetElementType()) + "&";
if (type.IsPointer)
return GetTypeDisplayName(type.GetElementType()) + "*";
if (type.IsArray)
return GetTypeDisplayName(type.GetElementType()) + "[]";
Type underlying = Nullable.GetUnderlyingType(type);
if (underlying != null)
return GetTypeDisplayName(underlying) + "?";
if (type.IsGenericType)
{
Type def = type.GetGenericTypeDefinition();
string baseName = def.FullName;
if (string.IsNullOrEmpty(baseName))
baseName = type.Name;
baseName = baseName.Replace('+', '.');
int backtick = baseName.IndexOf('`');
string cleanName = backtick > 0 ? baseName.Substring(0, backtick) : baseName;
Type[] genericArgs = type.GetGenericArguments();
StringBuilder sb = new StringBuilder();
sb.Append(cleanName);
sb.Append("<");
for (int i = 0; i < genericArgs.Length; i++)
{
sb.Append(GetTypeDisplayName(genericArgs[i]));
if (i < genericArgs.Length - 1)
sb.Append(", ");
}
sb.Append(">");
return sb.ToString();
}
if (type.FullName == null)
return type.Name;
return type.FullName.Replace('+', '.');
}
private static string GetTypeShortName(Type type)
{
if (type == null)
return "";
string name = type.Name;
int backtick = name.IndexOf('`');
if (backtick > 0)
name = name.Substring(0, backtick);
return name;
}
private static string Truncate(string value, int maxLength)
{
if (string.IsNullOrEmpty(value))
return string.Empty;
if (value.Length > maxLength)
return value.Substring(0, maxLength);
return value;
}
#endregion
#region 嵌套辅助类
/// <summary>
/// 服务方法信息。
/// </summary>
private class ServiceMethodInfo
{
internal ServiceMethodInfo(MethodInfo methodInfo, AjaxMethodAttribute methodAttribute)
{
_methodInfo = methodInfo;
_methodName = methodInfo.Name;
_isPublic = methodInfo.IsPublic;
_isStatic = methodInfo.IsStatic;
_returnType = methodInfo.ReturnType;
_authRequried = methodAttribute.AuthRequried;
_useHttpGet = methodAttribute.UseHttpGet;
}
private MethodInfo _methodInfo;
internal MethodInfo MethodInfo
{
get { return _methodInfo; }
}
private string _methodName;
public string MethodName
{
get { return _methodName == null ? string.Empty : _methodName; }
set { _methodName = value; }
}
private bool _isPublic;
public bool IsPublic
{
get { return _isPublic; }
set { _isPublic = value; }
}
private bool _isStatic;
public bool IsStatic
{
get { return _isStatic; }
set { _isStatic = value; }
}
private Type _returnType;
public Type ReturnType
{
get { return _returnType; }
set { _returnType = value; }
}
private bool _authRequried;
public bool AuthRequried
{
get { return _authRequried; }
set { _authRequried = value; }
}
private bool _useHttpGet;
public bool UseHttpGet
{
get { return _useHttpGet; }
set { _useHttpGet = value; }
}
private List<ServiceParameterInfo> _parameterList;
public List<ServiceParameterInfo> ParameterList
{
get { return _parameterList; }
set { _parameterList = value; }
}
internal void LoadMethodParameters()
{
if (_methodInfo == null)
return;
List<ServiceParameterInfo> list = new List<ServiceParameterInfo>();
int index = 0;
foreach (ParameterInfo param in _methodInfo.GetParameters())
{
list.Add(new ServiceParameterInfo(param, index));
index++;
}
_parameterList = list;
}
}
/// <summary>
/// 服务方法参数信息。
/// </summary>
private class ServiceParameterInfo
{
private ParameterInfo _param;
private int _index;
internal ServiceParameterInfo(ParameterInfo param, int index)
{
_param = param;
_index = index;
}
internal ParameterInfo ParameterInfo
{
get { return _param; }
}
internal int Index
{
get { return _index; }
}
public string Name
{
get { return _param.Name; }
}
public Type ParameterType
{
get { return _param.ParameterType; }
}
}
/// <summary>
/// XML 文档注释读取辅助类。
/// </summary>
private class XmlDocHelper
{
private XPathDocument _doc;
private XPathNavigator _nav;
public XmlDocHelper(string dllPath)
{
if (string.IsNullOrEmpty(dllPath))
return;
string fullPath = Path.GetFullPath(dllPath);
string dir = Path.GetDirectoryName(fullPath);
string xmlPath = Path.Combine(dir, Path.GetFileNameWithoutExtension(fullPath) + ".xml");
if (!File.Exists(xmlPath))
return;
try
{
_doc = new XPathDocument(xmlPath);
_nav = _doc.CreateNavigator();
}
catch
{
_doc = null;
_nav = null;
}
}
public string GetSummary(Type type)
{
if (_nav == null || type == null)
return "";
string id = GetTypeDocId(type);
return GetChildText("T", id, "summary");
}
public string GetSummary(MemberInfo member)
{
if (_nav == null || member == null)
return "";
string prefix = "P";
if (member is FieldInfo)
prefix = "F";
else if (member is PropertyInfo)
prefix = "P";
else if (member is MethodInfo)
prefix = "M";
string id = GetMemberDocId(member);
return GetChildText(prefix, id, "summary");
}
public string GetMethodSummary(MethodInfo method)
{
XPathNavigator node = FindMethodNode(method);
if (node == null)
return "";
XPathNavigator sum = node.SelectSingleNode("summary");
return sum == null ? "" : sum.Value.Trim();
}
public string GetMethodReturns(MethodInfo method)
{
XPathNavigator node = FindMethodNode(method);
if (node == null)
return "";
XPathNavigator ret = node.SelectSingleNode("returns");
return ret == null ? "" : ret.Value.Trim();
}
public string GetParameterSummary(MethodInfo method, string paramName)
{
XPathNavigator node = FindMethodNode(method);
if (node == null || string.IsNullOrEmpty(paramName))
return "";
string expr = "param[@name='" + Escape(paramName) + "']";
XPathNavigator pn = node.SelectSingleNode(expr);
return pn == null ? "" : pn.Value.Trim();
}
private string GetChildText(string prefix, string id, string childName)
{
if (_nav == null)
return "";
string expr = "//member[@name='" + prefix + ":" + Escape(id) + "']";
XPathNavigator node = _nav.SelectSingleNode(expr);
if (node == null)
return "";
XPathNavigator child = node.SelectSingleNode(childName);
return child == null ? "" : child.Value.Trim();
}
private XPathNavigator FindMethodNode(MethodInfo method)
{
if (_nav == null || method == null)
return null;
string exactId = GetMethodDocId(method);
string expr = "//member[@name='M:" + Escape(exactId) + "']";
XPathNavigator node = _nav.SelectSingleNode(expr);
if (node != null)
return node;
string typeId = GetTypeDocId(method.DeclaringType);
string prefix = "M:" + Escape(typeId) + "." + method.Name;
XPathNodeIterator iter = _nav.Select("//member[starts-with(@name,'" + prefix + "')]");
int pCount = method.GetParameters().Length;
while (iter.MoveNext())
{
string name = iter.Current.GetAttribute("name", "");
int open = name.IndexOf('(');
int close = name.LastIndexOf(')');
if (open > 0 && close > open)
{
string sig = name.Substring(open + 1, close - open - 1);
int count = string.IsNullOrEmpty(sig) ? 0 : CountChar(sig, ',') + 1;
if (count == pCount)
return iter.Current.Clone();
}
}
return null;
}
private static string GetTypeDocId(Type type)
{
if (type == null)
return "";
string fullName = type.FullName;
if (string.IsNullOrEmpty(fullName))
return type.Name;
return fullName.Replace('+', '.');
}
private static string GetMemberDocId(MemberInfo member)
{
Type type = member.DeclaringType;
string typeId = GetTypeDocId(type);
if (member is MethodInfo)
return GetMethodDocId((MethodInfo)member);
return typeId + "." + member.Name;
}
private static string GetMethodDocId(MethodInfo method)
{
StringBuilder sb = new StringBuilder();
sb.Append(GetTypeDocId(method.DeclaringType));
sb.Append(".");
sb.Append(method.Name);
if (method.IsGenericMethod)
sb.Append("``").Append(method.GetGenericArguments().Length);
sb.Append("(");
ParameterInfo[] ps = method.GetParameters();
for (int i = 0; i < ps.Length; i++)
{
if (i > 0)
sb.Append(",");
sb.Append(GetParameterDocTypeName(ps[i].ParameterType));
}
sb.Append(")");
return sb.ToString();
}
private static string GetParameterDocTypeName(Type type)
{
if (type == null)
return "";
if (type.IsGenericParameter)
return type.Name;
if (type.IsByRef)
return GetParameterDocTypeName(type.GetElementType()) + "@";
if (type.IsPointer)
return GetParameterDocTypeName(type.GetElementType()) + "*";
if (type.IsArray)
return GetParameterDocTypeName(type.GetElementType()) + "[]";
Type underlying = Nullable.GetUnderlyingType(type);
if (underlying != null)
return GetParameterDocTypeName(underlying) + "?";
if (type.IsGenericType)
{
Type def = type.GetGenericTypeDefinition();
string baseName = def.FullName;
if (string.IsNullOrEmpty(baseName))
baseName = type.Name;
baseName = baseName.Replace('+', '.');
Type[] args = type.GetGenericArguments();
StringBuilder sb = new StringBuilder();
sb.Append(baseName);
sb.Append("{");
for (int i = 0; i < args.Length; i++)
{
if (i > 0)
sb.Append(",");
sb.Append(GetParameterDocTypeName(args[i]));
}
sb.Append("}");
return sb.ToString();
}
string name = type.FullName;
if (string.IsNullOrEmpty(name))
name = type.Name;
return name.Replace('+', '.');
}
private static string Escape(string s)
{
if (s == null)
return "";
return s.Replace("'", "''");
}
private static int CountChar(string s, char c)
{
int count = 0;
for (int i = 0; i < s.Length; i++)
{
if (s[i] == c)
count++;
}
return count;
}
}
/// <summary>
/// 按成员名称排序的比较器。
/// </summary>
private class MemberNameComparer : IComparer<MemberInfo>
{
public int Compare(MemberInfo x, MemberInfo y)
{
return string.Compare(x.Name, y.Name, StringComparison.OrdinalIgnoreCase);
}
}
#endregion
}
}