Visual Studio可以做到这一点;反射器做到了;现在我也想:)
我想检索一些框架程序集中的一些成员(即mscorlib.dll
、System.dll
等)的XML文档。我认为这将涉及:
- 查找该程序集的XML文件
- 导航到适当命名的子元素,以及
- 检索所需项目(
<summary>
、<remarks>
等)
框架程序集的XML文件保存在哪里?关于破译XMLDOC命名方案有什么要点吗?有没有什么库可以让这个过程变得更容易?
查找xml
对于assembly.dll,它被命名为assembly.xml,但由Framework SDK安装,Runtime本身不包含.xml文件。用户不需要API文档。
位置有点复杂。它可以与dll并排,位于以当前区域设置命名的子目录中(例如C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\en),甚至位于附近某个奇怪的目录中。我建议以运行时查找附属程序集的方式搜索它。
查找元素
要查找元素,您应该从元数据中准备所谓的"xml-docID"。AFAIR它在C#语言规范中有文档,在MSDN中也有一些文档。请参阅处理XML文档。
基于Ilya的回应:
查找xml
.NET回退位置(忽略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 );
}
查找元素
处理XML文档
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 );
我在CodePlex上维护Jolt.NET项目,并实现了一个执行此任务的功能。有关更多信息,请参阅Jolt库。
本质上,该库允许您使用System.Reflection
中的元数据类型(即MethodInfo
、PropertyInfo
等)以编程方式定位和查询程序集的XML文档注释文件。
尝试DocsByReflection。
// From method.
var methodInfo = typeof(Stub).GetMethod("MethodWithGenericParameter");
var methodDoc = DocsService.GetXmlFromMember(methodInfo);
这里有一个现成的库,可以让您做到这一点:NuDochttp://kzu.to/nudoc
例如,阅读mscorlib上的整个文档,将非常简单:
var members = Reader.Read(typeof(string).Assembly);
稍后,您可以使用一个简单的访问者来处理结果,如网站上所示。
我正在利用该库生成一个API网站,使用markdown在GitHub中托管,理想情况下在每次构建时都会自动生成,甚至可能用于wiki,这样它就可以更新并四舍五入到代码中:)。
XML文件的名称与程序集的文件完全相同,只是扩展名不同,并且必须与程序集本身位于同一目录中。
不过不能帮你解决另外两个问题。AFAIK,你自己。。。