2008-10-23 58 views
3

Visual Studio做到這一點;反射器做它;現在我想和:)以編程方式檢索xml文檔註釋

我想檢索一些框架組件一些成員(即mscorlib.dllSystem.dll等)的XML文檔。我認爲這將涉及:

  • 找到了組裝的XML文件,
  • 導航到適當命名的子元素,並
  • 檢索所需的項目(<summary><remarks>等)


爲框架程序集保留的XML文件在哪裏?解密XMLDOC命名方案的任何要點?有沒有任何圖書館可以讓這個過程變得更簡單?

回答

5

查找XML

對於assembly.dll它被命名爲assembly.xml,而是由框架SDK安裝,運行時本身並不包含.xml文件。用戶不需要API文檔。

位置有點複雜。它可以與當前語言環境命名的子目錄(例如C:\ WINDOWS \ Microsoft.NET \ Framework \ v2.0.50727 \ en)或甚至在附近的某個奇怪的目錄中的dll並列。我建議以運行時查找衛星程序集的方式搜索它。

查找元素

要查找元素,你應該準備所謂的「XML的文檔ID」從元數據。 AFAIR在C#語言規範中有記載,在MSDN中有一點。見Processing XML documentation

0

除了不同的'xml'擴展名外,XML文件的命名與程序集文件完全相同,並且必須位於與程序集本身相同的目錄中。

雖然,不能幫你解決其他兩個問題。據我所知,你對自己的...

3

基於Ilya's response

查找XML

.NET fallback locations(忽略GAC和其它無關子目錄)

static FileInfo GetXmlDocFile(Assembly assembly) { 
    string assemblyDirPath = Path.GetDirectoryName(assembly.Location); 
    string fileName = Path.GetFileNameWithoutExtension(assembly.Location) +".xml"; 

    return GetFallbackDirectories(CultureInfo.CurrentCulture) 
    .Select(dirName => CombinePath(assemblyDirPath, dirName, fileName)) 
    .Select(filePath => new FileInfo(filePath)) 
    .Where(file => file.Exists) 
    .First(); 
} 

static IEnumerable<string> GetFallbackDirectories(CultureInfo culture) { 
    return culture 
    .Enumerate(c => c.Parent.Name != c.Name ? c.Parent : null) 
    .Select(c => c.Name); 
} 

static IEnumerable<T> Enumerate<T>(this T start, Func<T, T> next) { 
    for(T item = start; !object.Equals(item, default(T)); item = next(item)) 
    yield return item; 
} 

static string CombinePath(params string[] args) { 
    return args.Aggregate(Path.Combine); 
} 

查找元件

Processing XML Documentation

static XElement GetDocMember(XElement docMembers, MemberInfo member) { 
    string memberId = GetMemberId(member); 
    return docMembers.Elements("member") 
    .Where(e => e.Attribute("name").Value == memberId) 
    .First(); 
} 

static string GetMemberId(MemberInfo member) { 
    char memberKindPrefix = GetMemberPrefix(member); 
    string memberName = GetMemberFullName(member); 
    return memberKindPrefix + ":" + memberName; 
} 

static char GetMemberPrefix(MemberInfo member) { 
    return member.GetType().Name 
    .Replace("Runtime", "")[0]; 
} 

static string GetMemberFullName(MemberInfo member) { 
    string memberScope = ""; 
    if(member.DeclaringType != null) 
    memberScope = GetMemberFullName(member.DeclaringType); 
    else if(member is Type) 
    memberScope = ((Type)member).Namespace; 

    return memberScope + "." + member.Name; 
} 

使用示例

Type type = typeof(string); 

var file = GetXmlDocFile(type.Assembly); 
var docXml = XDocument.Load(file.FullName); 
var docMembers = docXml.Root.Element("members"); 

var member = type.GetProperty("Length"); 
var docMember = GetDocMember(docMembers, member); 
+0

請注意,這僅支持簡單成員(即字段和屬性),並且不支持方法參數。 – 2008-10-26 23:29:32

2

我保持在CodePlex上的Jolt.NET項目,並實施執行這個非常任務功能。請參閱Jolt圖書館瞭解更多信息。

在本質上,圖書館可以讓你以編程方式定位和System.Reflection使用元數據類型查詢XML文檔註釋文件組件(即MethodInfoPropertyInfo,等...)。

2

嘗試DocsByReflection

// From method. 
var methodInfo = typeof(Stub).GetMethod("MethodWithGenericParameter"); 
var methodDoc = DocsService.GetXmlFromMember(methodInfo); 
1

這裏有一個現成的庫,它可以讓你做到這一點:NuDoc http://kzu.to/nudoc

閱讀的mscorlib例如整個文檔,將簡單:

var members = Reader.Read(typeof(string).Assembly); 

您可以稍後使用簡單的訪問者處理結果,如網站上所示。

我正在利用該庫生成一個使用markdown在GitHub中進行託管的API站點,理想情況下可以在每個構建中自動生成一個API站點,甚至可以爲wiki維護,以便它可以更新並循環訪問代碼: )。

+0

該網頁似乎已移至http://www.cazzulino.com/NuDoq/。 GitHub:https://github.com/kzu/NuDoq。 – 2016-06-13 12:45:47