You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
It would be nice if you could alter the source generator to include adding the code to a partial class via a class with an attribute (Or some other means). It may be better to utilize an abstract class to do this where you can create your class from the abstract and the abstract class uses the attributes so that way the interface doesnt have to refer to the refit library.
Is your feature request related to a problem? Please describe.
The problem is that I want Separation of Concerns when it comes to my interfaces. I want the interface in one library and the client and all the framework dependencies in another. Much like what MS does with Abstractions libraries. The interface would be in the abstractions library while the client would be in the non-abstract library.
Describe the solution you'd like
Add another way for the source generator to choose the class it should implement. The refit source generator would detect the attribute and inspect the type being passed in to do the same code generation as before. The only difference is that the name of the class is exactly what we choose.
[RefitClient(typeof(IMyInterface))]
public partial class MyInterfaceClient
{
}
internal sealed class RefitSyntaxReceiver : ISyntaxReceiver
{
public List<ClassDeclarationSyntax> Classes { get; } = new List<ClassDeclarationSyntax>();
public void OnVisitSyntaxNode(SyntaxNode syntaxNode)
{
if (syntaxNode is ClassDeclarationSyntax classSyntax && HaveAttribute(classSyntax, "RefitClient"))
{
Classes.Add(classSyntax);
}
}
private bool HaveAttribute(ClassDeclarationSyntax classSyntax, string attributeName)
{
foreach (var attributeLists in classSyntax.AttributeLists)
{
foreach (var attribute in attributeLists.Attributes)
{
if (attribute.Name.NormalizeWhitespace().ToString() == attributeName)
{
return true;
}
}
}
return false;
}
}
Source Generator could find the interface like this...
foreach (var @class in syntaxReciver.Classes)
{
if (!TryGetParentSyntax(@class, out NamespaceDeclarationSyntax namespaceDeclarationSyntax))
{
throw new Exception($"Namespace not found for {@class.ToFullString()}");
}
var @interface = GetInterface(@class);
var type = context.Compilation.GetTypeByMetadataName($"{namespaceDeclarationSyntax.Name.ToString().Trim()}.{@interface}");
}
private string GetInterface(ClassDeclarationSyntax classSyntax)
{
foreach (var attributeLists in classSyntax.AttributeLists)
{
foreach (var attribute in attributeLists.Attributes)
{
if (attribute.Name.NormalizeWhitespace().ToString() == "RefitClient")
{
var argument = attribute.ArgumentList.Arguments[0];
return argument.Expression.ToString().Replace("typeof(", "").Replace(")", "");
}
}
}
return "Not Found";
}
public bool TryGetParentSyntax<T>(SyntaxNode syntaxNode, out T result)
where T : SyntaxNode
{
// set defaults
result = null;
if (syntaxNode == null)
{
return false;
}
try
{
syntaxNode = syntaxNode.Parent;
if (syntaxNode == null)
{
return false;
}
if (syntaxNode.GetType() == typeof(T))
{
result = syntaxNode as T;
return true;
}
return TryGetParentSyntax<T>(syntaxNode, out result);
}
catch
{
return false;
}
}
The text was updated successfully, but these errors were encountered:
tellybrown
changed the title
feature: Title
feature: Separation of Concerns with interface and client
Jun 25, 2021
Similar request to #542
It would be nice if you could alter the source generator to include adding the code to a partial class via a class with an attribute (Or some other means). It may be better to utilize an abstract class to do this where you can create your class from the abstract and the abstract class uses the attributes so that way the interface doesnt have to refer to the refit library.
Is your feature request related to a problem? Please describe.
The problem is that I want Separation of Concerns when it comes to my interfaces. I want the interface in one library and the client and all the framework dependencies in another. Much like what MS does with Abstractions libraries. The interface would be in the abstractions library while the client would be in the non-abstract library.
Describe the solution you'd like
Add another way for the source generator to choose the class it should implement. The refit source generator would detect the attribute and inspect the type being passed in to do the same code generation as before. The only difference is that the name of the class is exactly what we choose.
Source Generator could find the interface like this...
The text was updated successfully, but these errors were encountered: