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
{
///
/// 注释文档工具
///
public static class XmlDocUtils
{
private const string cacheKey = "XmlDoc";
///
/// 生成注释文档
///
///
public static async Task 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().SetStringAsync(cacheKey, json);
return xmlDoc;
}
return null;
}
///
/// 获取注释文档
///
///
public static async Task GetXmlDocAsync()
{
XmlDoc xmlDoc = null;
var json = await App.GetService().GetStringAsync(cacheKey);
if (!string.IsNullOrEmpty(json))
{
xmlDoc = JsonConvert.DeserializeObject(json);
}
if (xmlDoc == null)
{
xmlDoc = await BuildXmlDocAsync();
}
return xmlDoc;
}
///
/// 获取注释文档成员
///
///
///
///
public static async Task GetXmlDocMemberAsync(this MemberInfo memberInfo, XmlDoc xmlDoc = null)
{
if (xmlDoc == null)
{
var json = await App.GetService().GetStringAsync(cacheKey);
if (!string.IsNullOrEmpty(json))
{
xmlDoc = JsonConvert.DeserializeObject(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('+', '.') ?? "";
}
}
}