(1) 定义所有的类中所有成员的类:
[Serializable] public class TypeDefine { /// <summary> /// 主键Id /// </summary> public int Id { get; set; } /// <summary> /// 程序集名称 /// </summary> public string Assembly { get; set; } /// <summary> /// 命名空间 /// </summary> public string Namespace { get; set; } /// <summary> /// 类型 /// </summary> public string Type { get; set; } /// <summary> /// 成员类型(方法,属性,字段) /// </summary> public string MemberType { get; set; } /// <summary> /// 成员名称 /// </summary> public string MemberName { get; set; } /// <summary> /// 参数 /// </summary> public string Parameter { get; set; } /// <summary> /// 返回值类型 /// </summary> public string ReturnType { get; set; } /// <summary> /// 结果Hash值 /// </summary> public string Hash { get; set; } /// <summary> /// 版本号 /// </summary> public int Version { get; set; } /// <summary> /// 更改类型(1 新增,2 删除) /// </summary> public int EditType { get; set; } /// <summary> /// 接口类型 /// </summary> public string InterfaceType { get; set; } /// <summary> /// 实际版本 /// </summary> public string RealVersion { get; set; } /// <summary> /// 获取Hash /// </summary> /// <returns></returns> public void SetHash() { string key = $"{this.Namespace}-{this.Assembly}-{this.Type}-{this.MemberType}-{this.MemberName}-{this.Parameter}-{this.ReturnType}"; var input = Encoding.UTF8.GetBytes(key); MD5 md5 = MD5.Create(); var result = md5.ComputeHash(input); StringBuilder sb = new StringBuilder(); foreach (byte b in result) { sb.Append(b.ToString("X2")); } this.Hash= sb.ToString(); } }
(2)扫描所有的dll
/// <summary>
/// 扫描后端
/// </summary>
/// <param name="filePath">bin目录</param>
private List<TypeDefine> ScanBack(string filePath)
{
var path = filePath + "\\bin";
List<string> excludeList = null;
string excludeConfig = ConfigurationManager.AppSettings["excludeDll"];
if (string.IsNullOrEmpty(excludeConfig) == false)
{
excludeList = excludeConfig.Split(",".ToCharArray(), StringSplitOptions.RemoveEmptyEntries).ToList();
}
List<TypeDefine> allResult = new List<TypeDefine>();
foreach (var file in Directory.GetFiles(path, "*.dll"))
{
string fi = Path.GetFileName(file);
//排除不需要扫描的dll
if (excludeList != null && excludeList.Contains(fi))
{
continue;
}
var assebmly = Assembly.LoadFrom(file);
foreach (var type in assebmly.GetExportedTypes())
{
var result = GetExport(fi, type);
if (result?.Count > 0)
{
allResult.AddRange(result);
}
}
}
return allResult;
}
(3)解析类型的所有的方法、属性等
private List<TypeDefine> GetExport(string fileName, Type type)
{
List<TypeDefine> allResult = new List<TypeDefine>();
string ns = type.Namespace;
string assembly = fileName;
string typeName = GetFriendlyName(type);
BindingFlags flag = BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static;
foreach (var mi in type.GetMethods(flag))
{
var model = new TypeDefine()
{
Namespace = ns,
Assembly = assembly,
Type = typeName
};
if (mi.DeclaringType == typeof(object))
{
continue;
}
if (mi.Name.StartsWith("get_")
|| mi.Name.StartsWith("set_")
|| mi.Name.StartsWith("add_")
|| mi.Name.StartsWith("remove_"))
{
continue; ;
}
model.MemberType = "方法";
model.MemberName = mi.Name;
StringBuilder sb = new StringBuilder();
sb.Append("(");
bool bDone = true;
foreach (var p in mi.GetParameters())
{
if (bDone)
{
bDone = false;
sb.AppendFormat("{0} {1}", GetFriendlyName(p.ParameterType), p.Name);
}
else
{
sb.AppendFormat(", {0} {1}", GetFriendlyName(p.ParameterType), p.Name);
}
}
sb.Append(")");
model.Parameter = sb.ToString();
model.ReturnType = GetFriendlyName(mi.ReturnType);
allResult.Add(model);
}
foreach (var pi in type.GetProperties(flag))
{
var model = new TypeDefine();
model.MemberType = "属性";
model.MemberName = pi.Name;
allResult.Add(model);
}
foreach (var fi in type.GetFields(flag))
{
var model = new TypeDefine();
if (fi.Name == "value__")
{
continue;
}
model.MemberType = "字段";
model.MemberName = fi.Name;
allResult.Add(model);
}
foreach (var evt in type.GetEvents(flag))
{
var model = new TypeDefine();
model.MemberType = "事件";
model.MemberName = evt.Name;
allResult.Add(model);
}
foreach (var obj in allResult)
{
obj.Namespace = ns;
obj.Assembly = assembly;
obj.Type = typeName;
obj.InterfaceType = "后端";
}
return allResult;
}