<PackageReference Include="NJsonSchema" Version="1.28.5872.19133" />

XmlDocumentationExtensions

public static class XmlDocumentationExtensions
Provides extension methods for reading XML comments from reflected members.
using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Xml.Linq; namespace NJsonSchema.Infrastructure { public static class XmlDocumentationExtensions { private static readonly object _lock = new object(); private static readonly Dictionary<string, XDocument> _cache = new Dictionary<string, XDocument>(StringComparer.OrdinalIgnoreCase); public static string GetXmlDocumentation(this Type type) { return ((MemberInfo)type.GetTypeInfo()).GetXmlDocumentation(); } public static string GetXmlDocumentation(this MemberInfo member) { if (!FullDotNetMethods.SupportsFullDotNetMethods) return string.Empty; lock (_lock) { AssemblyName name = member.Module.Assembly.GetName(); if (_cache.ContainsKey(name.FullName) && _cache[name.FullName] == null) return string.Empty; return member.GetXmlDocumentation(GetXmlDocumentationPath(member.Module.Assembly)); } } public static string GetXmlDocumentation(this ParameterInfo parameter) { if (!FullDotNetMethods.SupportsFullDotNetMethods) return string.Empty; lock (_lock) { AssemblyName name = parameter.Member.Module.Assembly.GetName(); if (_cache.ContainsKey(name.FullName) && _cache[name.FullName] == null) return string.Empty; return parameter.GetXmlDocumentation(GetXmlDocumentationPath(parameter.Member.Module.Assembly)); } } public static string GetXmlDocumentation(this Type type, string pathToXmlFile) { return ((MemberInfo)type.GetTypeInfo()).GetXmlDocumentation(pathToXmlFile); } public static string GetXmlDocumentation(this MemberInfo member, string pathToXmlFile) { try { lock (_lock) { if (pathToXmlFile != null && FullDotNetMethods.SupportsFullDotNetMethods) { AssemblyName name = member.Module.Assembly.GetName(); if (_cache.ContainsKey(name.FullName) && _cache[name.FullName] == null) return string.Empty; if (FullDotNetMethods.FileExists(pathToXmlFile)) { if (!_cache.ContainsKey(name.FullName)) _cache[name.FullName] = XDocument.Load(pathToXmlFile); return member.GetXmlDocumentation(_cache[name.FullName]); } _cache[name.FullName] = null; return string.Empty; } return string.Empty; } } catch { return string.Empty; } } public static string GetXmlDocumentation(this ParameterInfo parameter, string pathToXmlFile) { try { lock (_lock) { if (pathToXmlFile != null && FullDotNetMethods.SupportsFullDotNetMethods) { AssemblyName name = parameter.Member.Module.Assembly.GetName(); if (_cache.ContainsKey(name.FullName) && _cache[name.FullName] == null) return string.Empty; if (FullDotNetMethods.FileExists(pathToXmlFile)) { if (!_cache.ContainsKey(name.FullName)) _cache[name.FullName] = XDocument.Load(pathToXmlFile); return parameter.GetXmlDocumentation(_cache[name.FullName]); } _cache[name.FullName] = null; return string.Empty; } return string.Empty; } } catch { return string.Empty; } } private static string GetXmlDocumentation(this MemberInfo member, XDocument xml) { string memberElementName = GetMemberElementName(member); return FullDotNetMethods.XPathEvaluate(xml, $"""{new object[1] { memberElementName }}""").ToString().Trim(); } private static string GetXmlDocumentation(this ParameterInfo parameter, XDocument xml) { string memberElementName = GetMemberElementName(parameter.Member); if (parameter.IsRetval || string.IsNullOrEmpty(parameter.Name)) return FullDotNetMethods.XPathEvaluate(xml, $"""{new object[1] { memberElementName }}""").ToString().Trim(); return FullDotNetMethods.XPathEvaluate(xml, string.Format("string(/doc/members/member[@name='{0}']/param[@name='{1}'])", new object[2] { memberElementName, parameter.Name })).ToString().Trim(); } private static string GetMemberElementName(dynamic member) { string text = (string)((member is Type) ? ((Type)member).FullName : (member.DeclaringType.FullName + "." + member.Name)); char c; switch ((string)member.MemberType.ToString()) { case "Constructor": text = text.Replace(".ctor", "#ctor"); goto case "Method"; case "Method": { c = 'M'; string text2 = string.Join(",", (from x in ((MethodBase)member).GetParameters() select x.ParameterType.FullName).ToArray()); if (!string.IsNullOrEmpty(text2)) text = text + "(" + text2 + ")"; break; } case "Event": c = 'E'; break; case "Field": c = 'F'; break; case "NestedType": text = text.Replace('+', '.'); goto case "TypeInfo"; case "TypeInfo": c = 'T'; break; case "Property": c = 'P'; break; default: throw new ArgumentException("Unknown member type.", "member"); } return string.Format("{0}:{1}", new object[2] { c, text }); } private static string GetXmlDocumentationPath(dynamic assembly) { dynamic val = assembly.GetName(); dynamic val2 = FullDotNetMethods.PathCombine(FullDotNetMethods.PathGetDirectoryName(assembly.Location), val.Name + ".xml"); if (FullDotNetMethods.FileExists(val2)) return (string)val2; dynamic value = Type.GetType("System.AppDomain").GetRuntimeProperty("CurrentDomain").GetValue(null); val2 = FullDotNetMethods.PathCombine(value.BaseDirectory, val.Name + ".xml"); if (FullDotNetMethods.FileExists(val2)) return (string)val2; return (string)FullDotNetMethods.PathCombine(value.BaseDirectory, "bin\\" + val.Name + ".xml"); } } }