I have written a C# interface and compiled it into Contract.dll. The Contract.dll is referenced by an ASP.NET MVC website (the client in this scenario) and an ASP.NET Web API service.
I use Refit in the website to call the service. I tried using a constant from the Contract.dll in Refit's Get attribute and Web API's HttpGet attribute to indicate the service method URL. This would allow me to specify the URL in one place and have it reference by client and service.
Client
public static class WidgetServiceUrls
{
public const string ListByName = "/widget/list/{Name}";
}
public interface IWidgetService
{
// Refit requires a string literal URL, not a constant. Ensure the implementing service uses the same URL.
[Get(WidgetServiceUrls.ListByName)]
Task<List<Widget>> List(string Name);
}
Service
// TODO: Determine how to eliminate duplicate URL string in service controller action and interface method.
[HttpGet(WidgetServiceUrls.ListByName)]
public async Task<List<Widget>> List(string Name)
Refit throws an exception when calling RestService.For(httpClient):
IWidgetService doesn't look like a Refit interface. Make sure it has at least one method with a Refit HTTP method attribute and Refit is installed in the project.
Apparently, Refit doesn't understand the constant in the Get attribute. If I use a string literal in both places, the code executes correctly. However, now I've violated the DRY principle by repeating the URL in two places.
How can I annotate interfaces in Contract.dll so the Refit client and Web API service method use the same URL?