Skip to content

Instantly share code, notes, and snippets.

@robfe
Created November 16, 2011 11:41
Show Gist options
  • Save robfe/1369896 to your computer and use it in GitHub Desktop.
Save robfe/1369896 to your computer and use it in GitHub Desktop.
Documents the webget and webinvoke methods of a ServiceContract
[TestClass]
public class ApiDocumentor
{
[TestMethod]
public void PrintApiMethods()
{
var methods = from m in typeof(Api).GetMethods()
let url = GetUrl(m)
where url != null
select new { url, m };
foreach (var method in methods)
{
Console.Out.WriteLine("({1}) {0} ({2})", method.url, method.m.ReturnType.Name, string.Join(", ", method.m.GetParameters().Select(x => x.ParameterType.Name + " " + x.Name)));
}
new TypePrinter().PrintTypes(methods.Select(x => x.m.ReturnType));
}
string GetUrl(MethodInfo m)
{
var webInvoke = (WebInvokeAttribute)Attribute.GetCustomAttribute(m, typeof(WebInvokeAttribute));
if (webInvoke != null)
{
return webInvoke.Method + " /" + webInvoke.UriTemplate;
}
var webGet = (WebGetAttribute)Attribute.GetCustomAttribute(m, typeof(WebGetAttribute));
if (webGet != null)
{
return "GET /" + webGet.UriTemplate;
}
return null;
}
public class TypePrinter
{
readonly HashSet<Type> printedTypes = new HashSet<Type>();
Stack<Type> typesToPrint;
public void PrintTypes(IEnumerable<Type> initialTypes)
{
typesToPrint = new Stack<Type>(initialTypes.Distinct());
while (typesToPrint.Count != 0)
{
PrintType(typesToPrint.Pop());
}
}
void PrintType(Type type)
{
printedTypes.Add(type);
if (type == typeof(void))
{
return;
}
Console.Out.WriteLine(type.Name);
bool isDataContract = Attribute.IsDefined(type, typeof(DataContractAttribute));
var propertyInfos = type.GetProperties().AsEnumerable();
if (isDataContract)
{
propertyInfos = propertyInfos.Where(x => Attribute.IsDefined(x, typeof(DataMemberAttribute)));
}
foreach (var p in propertyInfos)
{
Type propertyType = p.PropertyType;
Console.Out.WriteLine("\t" + DecribePropertyType(propertyType) + " " + p.Name);
}
Console.Out.WriteLine();
}
void MaybeAddType(Type propertyType)
{
if (!typesToPrint.Contains(propertyType)
&& !printedTypes.Contains(propertyType)
&& !propertyType.Namespace.StartsWith("System")
&& !propertyType.Namespace.StartsWith("Microsoft"))
{
typesToPrint.Push(propertyType);
}
}
string DecribePropertyType(Type propertyType)
{
if (propertyType == typeof(string))
{
return "string";
}
if (propertyType.IsGenericType && propertyType.GetInterfaces().Select(x => x.GetGenericTypeDefinition()).Contains(typeof(IEnumerable<>)))
{
Type t = propertyType.GetGenericArguments().First();
MaybeAddType(t);
return t.Name + "[]";
}
MaybeAddType(propertyType);
return propertyType.Name;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment