The Reflector class below generates an HTML document outlining the public API for a given assembly.
First, an XML document is emitted in memory (see Emit*()).
The document captures the relevant aspects of the assembly's metadata.
Next, an HTML document is extracted from the XML document (see Extract*()).
I love Linq.
Public Class Reflector Public document As XDocument Public Sub Reflect(ByVal assemblyFile As String) Dim Assembly As Assembly = Assembly.LoadFrom(assemblyFile) document = New XDocument(EmitAssembly(Assembly)) End Sub Public Sub Transform(ByVal writer As XmlWriter) If document Is Nothing Then Return Dim assembly As XElement = document.Element("assembly") Dim transform As New XDocument(ExtractAssembly(assembly)) transform.Save(writer) End Sub Public Function EmitAssembly(ByVal assembly As Assembly) As XElement Return End Function Public Function EmitNamespace(ByVal ns As String, ByVal types As IEnumerable(Of Type)) As XElement Return End Function Public Function EmitType(ByVal type As Type) As XElement Return < name=> > End Function Public Function EmitGenericArguments(ByVal args As IEnumerable(Of Type)) As IEnumerable(Of XElement) Return From arg In args _ Select End Function Public Function EmitModifiers(ByVal type As Type) As XElement Dim builder As StringBuilder = New StringBuilder() If type.IsPublic Then builder.Append("public") ElseIf type.IsNestedPublic Then builder.Append("public") ElseIf type.IsNestedFamily Then builder.Append("protected") ElseIf type.IsNestedFamANDAssem Then builder.Append("protected internal") End If If type.IsSealed Then builder.Append(" sealed") If type.IsAbstract Then builder.Append(" abstract") Return End Function Public Function EmitExtends(ByVal baseType As Type) As XElement If baseType Is Nothing Or baseType Is GetType(Object) Or baseType Is GetType(ValueType) Or baseType Is GetType(System.Enum) Then Return Nothing Return End Function Public Function EmitImplements(ByVal ifaces As IEnumerable(Of Type)) As IEnumerable(Of XElement) Return From iface In ifaces _ Select End Function Public Function EmitDeclaringType(ByVal declaringType As Type) As XElement If declaringType Is Nothing Then Return Nothing Return End Function Public Function EmitNestedTypes(ByVal ntypes As IEnumerable(Of Type)) As IEnumerable(Of XElement) Return From ntype In ntypes _ Where GetVisible(ntype) _ Select EmitType(ntype) End Function Public Function EmitMethods(ByVal metds As IEnumerable(Of MethodBase)) As IEnumerable(Of XElement) Return From metd In metds _ Where GetVisible(metd) _ Select End Function Public Function EmitProperties(ByVal props As IEnumerable(Of PropertyInfo)) As IEnumerable(Of XElement) Return From prop In props _ Where GetVisible(prop.GetGetMethod()) Or _ GetVisible(prop.GetSetMethod()) _ Select End Function Public Function EmitReference(ByVal type As Type) As IEnumerable(Of Object) If (Not type.IsGenericType) Then Return New Object() {New XAttribute("name", type.Name), _ New XAttribute("namespace", GetNamespace(type))} Else Return New Object() {New XAttribute("name", type.Name), _ New XAttribute("namespace", GetNamespace(type)), _ EmitGenericArguments(type.GetGenericArguments())} End If End Function Public Function EmitModifiers(ByVal metd As MethodBase) As XElement Dim builder As StringBuilder = New StringBuilder() If metd.IsPublic Then builder.Append("public") ElseIf metd.IsFamily Then builder.Append("protected") ElseIf metd.IsFamilyAndAssembly Then builder.Append("protected internal") End If If metd.IsAbstract Then builder.Append(" abstract") If metd.IsStatic Then builder.Append(" static") If metd.IsVirtual Then builder.Append(" virtual") Return New XElement("modifiers", builder.ToString()) End Function Public Function EmitReturnType(ByVal metd As MethodBase) As XElement Dim metdInfo As MethodInfo = TryCast(metd, MethodInfo) If metdInfo Is Nothing Then Return Nothing Return End Function Public Function EmitExtension(ByVal metd As MethodBase) As XElement Return End Function Public Function EmitParameters(ByVal parms As IEnumerable(Of ParameterInfo)) As IEnumerable(Of XElement) Return From parm In parms _ Select End Function Public Shared Function GetNamespace(ByVal type As Type) As String Dim ns As String = type.Namespace Return If(ns IsNot Nothing, ns, String.Empty) End Function Public Shared Function GetVisible(ByVal type As Type) As Boolean Return type.IsPublic Or type.IsNestedPublic Or type.IsNestedFamily Or type.IsNestedFamANDAssem End Function Public Shared Function GetVisible(ByVal metd As MethodBase) As Boolean Return metd IsNot Nothing AndAlso (metd.IsPublic Or metd.IsFamily Or metd.IsFamilyAndAssembly) End Function Public Function ExtractAssembly(ByVal assembly As XElement) As XElement Return Assembly: End Function Public Function ExtractNamespace(ByVal ns As XElement) As XElement Return Namespace: End Function Public Function ExtractType(ByVal type As XElement) As XElement Return End Function Public Function ExtractModifiers(ByVal element As XElement) As String Return element.Element("modifiers").Value End Function Public Function ExtractName(ByVal element As XElement) As String Dim name As String = element.Attribute("name").Value Dim i As Integer = name.LastIndexOf("`") If i > 0 Then name = name.Substring(0, i) ' fix generic name Return name End Function Public Function ExtractGenericArguments(ByVal element As XElement) As String If Not element.Elements("genericArgument").Any() Then Return String.Empty Dim builder As StringBuilder = New StringBuilder("<") For Each genericArgument As XElement In element.Elements("genericArgument") If builder.Length <> 1 Then builder.Append(", ") builder.Append(ExtractReference(genericArgument)) Next builder.Append(">") Return builder.ToString() End Function Public Function ExtractReference(ByVal element As XElement) As String Return ExtractName(element) + ExtractGenericArguments(element) End Function Public Function ExtractInherits(ByVal type As XElement) As String If Not type.Elements("extends").Concat(type.Elements("implements")).Any() Then Return String.Empty Dim builder As New StringBuilder() For Each [inherits] As XElement In type.Elements("extends").Concat(type.Elements("implements")) If builder.Length = 0 Then builder.Append(" : ") Else builder.Append(", ") End If builder.Append(ExtractReference([inherits])) Next Return builder.ToString() End Function Public Function ExtractConstructors(ByVal type As XElement) As XElement Dim ctors = From ctor In type.Elements("method") _ Where ExtractName(ctor) = ".ctor" _ Select