Skip to content

Commit

Permalink
Add support for composing refit interfaces using properties
Browse files Browse the repository at this point in the history
  • Loading branch information
nekresh committed Dec 6, 2014
1 parent 9219181 commit 90d1e67
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 1 deletion.
18 changes: 18 additions & 0 deletions InterfaceStubGenerator/GeneratedInterfaceStubTemplate.mustache
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,24 @@ namespace {{Namespace}}
}

{{/MethodList}}

{{#PropertyList}}
public {{Type}} {{Name}}
{
{{#IsRefitProperty}}
get
{
var attribute = GetType().GetInterfaceMap(typeof({{InterfaceName}}{{#TypeParameters}}<{{.}}>{{/TypeParameters}})).InterfaceType
.GetProperty("{{Name}}").GetCustomAttributes(typeof(Refit.ComposeAttribute), false)
.OfType<Refit.ComposeAttribute>().FirstOrDefault();
return Refit.RestService.For<{{Type}}>(new Uri(Client.BaseAddress, attribute.Uri).AbsoluteUri);
}
{{/IsRefitProperty}}
{{^IsRefitProperty}}
get { throw new NotImplementedException("This property has no Refit composition attribute."); }
{{/IsRefitProperty}}
}
{{/PropertyList}}
}
}

Expand Down
30 changes: 29 additions & 1 deletion InterfaceStubGenerator/InterfaceStubGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@ public List<InterfaceDeclarationSyntax> FindInterfacesToGenerate(SyntaxTree tree
return new List<InterfaceDeclarationSyntax>();

return nodes.OfType<InterfaceDeclarationSyntax>()
.Where(i => i.Members.OfType<MethodDeclarationSyntax>().Any(HasRefitHttpMethodAttribute))
.Where(i => i.Members.OfType<MethodDeclarationSyntax>().Any(HasRefitHttpMethodAttribute) ||
i.Members.OfType<PropertyDeclarationSyntax>().Any(HasInterfaceCompositionAttribute))
.ToList();
}

Expand All @@ -70,6 +71,16 @@ public bool HasRefitHttpMethodAttribute(MethodDeclarationSyntax method)
a.ArgumentList.Arguments[0].Expression.CSharpKind() == SyntaxKind.StringLiteralExpression);
}

static readonly HashSet<string> interfaceCompositionAttributeNames = new HashSet<string>(
new[] {"Compose"}
.SelectMany(x => new[] {"{0}", "{0}Attribute"}.Select(f => string.Format(f, x))));

public bool HasInterfaceCompositionAttribute(PropertyDeclarationSyntax property)
{
return property.AttributeLists.SelectMany(a => a.Attributes)
.Any(a => interfaceCompositionAttributeNames.Contains(a.Name.ToString().Split('.').Last()));
}

public TemplateInformation GenerateTemplateInfoForInterfaceList(List<InterfaceDeclarationSyntax> interfaceList)
{
var usings = interfaceList
Expand Down Expand Up @@ -123,6 +134,15 @@ public ClassTemplateInfo GenerateClassInfoForInterface(InterfaceDeclarationSynta
})
.ToList();

ret.PropertyList = interfaceTree.Members
.OfType<PropertyDeclarationSyntax>()
.Select(x => new PropertyTemplateInfo() {
Name = x.Identifier.ValueText,
Type = x.Type.ToString(),
IsRefitProperty = HasInterfaceCompositionAttribute(x)
})
.ToList();

return ret;
}

Expand Down Expand Up @@ -156,6 +176,7 @@ public class ClassTemplateInfo
public string TypeParameters { get; set; }
public string ConstraintClauses { get; set; }
public List<MethodTemplateInfo> MethodList { get; set; }
public List<PropertyTemplateInfo> PropertyList { get; set; }
}

public class MethodTemplateInfo
Expand All @@ -167,6 +188,13 @@ public class MethodTemplateInfo
public bool IsRefitMethod { get; set; }
}

public class PropertyTemplateInfo
{
public string Type { get; set; }
public string Name { get; set; }
public bool IsRefitProperty { get; set; }
}

public class TemplateInformation
{
public List<UsingDeclaration> UsingList { get; set; }
Expand Down
11 changes: 11 additions & 0 deletions Refit/Attributes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -115,4 +115,15 @@ public HeaderAttribute(string header)
Header = header;
}
}

[AttributeUsage(AttributeTargets.Property)]
public class ComposeAttribute : Attribute
{
public string Uri { get; private set; }

public ComposeAttribute(string uri)
{
Uri = uri;
}
}
}

0 comments on commit 90d1e67

Please sign in to comment.