using Furion;
|
using Furion.DatabaseAccessor;
|
using Furion.DataEncryption;
|
using MediatR;
|
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore.Metadata.Internal;
|
using Microsoft.Extensions.Caching.Distributed;
|
using Newtonsoft.Json;
|
using System;
|
using System.Collections.Generic;
|
using System.IO;
|
using System.Linq;
|
using System.Reflection;
|
using System.Text;
|
using System.Threading.Tasks;
|
using System.Xml;
|
|
namespace FlexJobApi.Core
|
{
|
/// <summary>
|
/// 注释文档工具
|
/// </summary>
|
public static class XmlDocUtils
|
{
|
private const string cacheKey = "XmlDoc";
|
|
/// <summary>
|
/// 生成注释文档
|
/// </summary>
|
/// <returns></returns>
|
public static async Task<XmlDoc> BuildXmlDocAsync()
|
{
|
var xmlDoc = new XmlDoc();
|
foreach (var item in App.Assemblies)
|
{
|
var path = item.Location.Replace("dll", "xml");
|
if (File.Exists(path))
|
{
|
var document = new XmlDocument();
|
document.Load(path);
|
var memberNodes = document.SelectNodes("//member");
|
if (memberNodes != null)
|
{
|
foreach (XmlNode memberNode in memberNodes)
|
{
|
var memberName = memberNode.Attributes?["name"]?.Value;
|
if (!string.IsNullOrEmpty(memberName))
|
{
|
var member = new XmlDocMember
|
{
|
Name = memberName,
|
Summary = memberNode.SelectSingleNode("summary")?.InnerText?.Trim(),
|
Returm = memberNode.SelectSingleNode("returns")?.InnerText?.Trim()
|
};
|
var paramNodes = memberNode.SelectNodes("param");
|
if (paramNodes != null)
|
{
|
foreach (XmlNode paramNode in paramNodes)
|
{
|
var paramNodeName = paramNode.Attributes?["name"]?.Value;
|
if (!string.IsNullOrEmpty(paramNodeName))
|
{
|
member.Parameters.Add(new XmlDocMember
|
{
|
Name = paramNodeName,
|
Summary = paramNode.InnerText?.Trim()
|
});
|
}
|
}
|
}
|
xmlDoc.Members.Add(member);
|
}
|
}
|
}
|
}
|
}
|
|
if (xmlDoc.Members.Any())
|
{
|
var json = JsonConvert.SerializeObject(xmlDoc);
|
await App.GetService<IDistributedCache>().SetStringAsync(cacheKey, json);
|
return xmlDoc;
|
}
|
return null;
|
}
|
|
/// <summary>
|
/// 获取注释文档
|
/// </summary>
|
/// <returns></returns>
|
public static async Task<XmlDoc> GetXmlDocAsync()
|
{
|
XmlDoc xmlDoc = null;
|
var json = await App.GetService<IDistributedCache>().GetStringAsync(cacheKey);
|
if (!string.IsNullOrEmpty(json))
|
{
|
xmlDoc = JsonConvert.DeserializeObject<XmlDoc>(json);
|
}
|
if (xmlDoc == null)
|
{
|
xmlDoc = await BuildXmlDocAsync();
|
}
|
return xmlDoc;
|
}
|
|
/// <summary>
|
/// 获取注释文档成员
|
/// </summary>
|
/// <param name="memberInfo"></param>
|
/// <param name="xmlDoc"></param>
|
/// <returns></returns>
|
public static async Task<XmlDocMember> GetXmlDocMemberAsync(this MemberInfo memberInfo, XmlDoc xmlDoc = null)
|
{
|
if (xmlDoc == null)
|
{
|
var json = await App.GetService<IDistributedCache>().GetStringAsync(cacheKey);
|
if (!string.IsNullOrEmpty(json))
|
{
|
xmlDoc = JsonConvert.DeserializeObject<XmlDoc>(json);
|
}
|
}
|
if (xmlDoc == null)
|
{
|
xmlDoc = await BuildXmlDocAsync();
|
}
|
if (xmlDoc != null && memberInfo != null)
|
{
|
var memberName = GetXmlDocMemberName(memberInfo);
|
return xmlDoc.Members.FirstOrDefault(it => it.Name == memberName);
|
}
|
return null;
|
}
|
|
private static string GetXmlDocMemberName(MemberInfo memberInfo)
|
{
|
if (memberInfo != null)
|
{
|
if (memberInfo is Type type)
|
{
|
return $"T:{GetTypeName(type)}";
|
}
|
else if (memberInfo is MethodInfo methodInfo && methodInfo.DeclaringType != null)
|
{
|
var methodName = $"M:{GetTypeName(methodInfo.DeclaringType)}.{methodInfo.Name}";
|
var parameters = methodInfo.GetParameters();
|
if (parameters.Length > 0)
|
{
|
methodName += $"({string.Join(",", parameters.Select(p => GetTypeName(p.ParameterType)))})";
|
}
|
return methodName;
|
}
|
else if (memberInfo is FieldInfo fieldInfo && fieldInfo.DeclaringType != null)
|
{
|
return $"F:{GetTypeName(fieldInfo.DeclaringType)}.{fieldInfo.Name}";
|
}
|
else if (memberInfo is PropertyInfo propertyInfo && propertyInfo.DeclaringType != null)
|
{
|
return $"P:{GetTypeName(propertyInfo.DeclaringType)}.{propertyInfo.Name}";
|
}
|
}
|
return string.Empty;
|
}
|
|
private static string GetTypeName(Type type)
|
{
|
if (type.IsGenericType)
|
{
|
var genericTypeDefinition = type.GetGenericTypeDefinition();
|
var genericArguments = type.GetGenericArguments();
|
var baseName = genericTypeDefinition.FullName?.Replace('+', '.') ?? "";
|
baseName = baseName.Substring(0, baseName.IndexOf('`'));
|
return $"{baseName}`{genericArguments.Length}";
|
}
|
else if (type.IsArray)
|
{
|
var elementType = type.GetElementType();
|
if (elementType != null)
|
{
|
return $"{GetTypeName(elementType)}[]";
|
}
|
}
|
else if (type.IsNested && type.DeclaringType != null)
|
{
|
return $"{GetTypeName(type.DeclaringType)}+{type.Name}";
|
}
|
return type.FullName?.Replace('+', '.') ?? "";
|
}
|
}
|
}
|