refit
refit copied to clipboard
[BUG] Refit does not recognize generated interface
Describe the bug
We've been playing around with generating Refit interfaces using the CodeAnalyzer and so far we've been able to generate an interface that, to us, looks like an interface that Refit would accept. However, we've been unable to register it with Refit since we only get the exception below.
Unhandled Exception: System.InvalidOperationException: ISetAPIClient 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.
at Refit.RestService.GetGeneratedType(Type refitInterfaceType) in /_/Refit/RestService.cs:line 173
at Refit.RestService.For(Type refitInterfaceType, HttpClient client, IRequestBuilder builder) in /_/Refit/RestService.cs:line 76
at Refit.RestService.For[T](HttpClient client, IRequestBuilder`1 builder) in /_/Refit/RestService.cs:line 20
at Customer.WebServices.API.Client.ClientBase.DoStuff() in C:\projects\customer\Customer.Webservices.Backend\generated\Customer.WebServices.API.Client\ClientBase.cs:line 19
at Customer.WebServices.API.Client.ClientBase.Main() in C:\projects\customer\Customer.Webservices.Backend\generated\Customer.WebServices.API.Client\ClientBase.cs:line 12
The interface gets generated at build time and published as a NuGet package, and looks like the following:
Generated file
// This files was auto-generated. Do not modify this file
namespace Customer.WebServices.API.Client
{
public interface ISetAPIClient
{
[Refit.Get("/Sets")]
System.Threading.Tasks.Task<System.Collections.Generic.IEnumerable<Customer.Webservices.Core.Models.Set>> GetSets();
[Refit.Get("/Sets/{id}")]
System.Threading.Tasks.Task<System.Collections.Generic.IEnumerable<Customer.Webservices.Core.Models.Set>> GetSets(int id);
}
}
(Yes the case on Webservices/WebServices are different, this is going to be changed)
Inspected NuGet package in different project
using Customer.Webservices.Core.Interfaces;
using Customer.Webservices.Core.Models;
using Refit;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace Customer.WebServices.API.Client
{
public interface ISetAPIClient
{
[Get("/Sets")]
Task<IEnumerable<Set>> GetSets();
[Get("/Sets/{id}")]
Task<IEnumerable<Set>> GetSets(int id);
}
}
I've tried consuming the interface the following ways with no success
RestService.For<ISetAPIClient>("http://localhost:12345");
services.AddRefitClient<ISetAPIClient>()
.ConfigureHttpClient(options => options.BaseAddress = new Uri("https://localhost:44341"));
but neither times Refit recognized the Interface.
We've tried copying the generated interface into a different source file, and Refit seems to accept that interface. Why it does not accept the generated one or the NuGet interface is something we cannot figure out.
Environment
- OS: Windows 10
- Version: 5.2.4 and 6.3.2 (Both times all projects used the same packages)
- Runtime: .NET 5
I'm facing the same issue, as far as I looked up some of the previous ones there is no clear solution for this, I was using encryption so I thought it might be the case but I even removed the encryption, and still the same result "... doesn't look like a Refit interface".
I have same issue. This occurs randomly when compiling the app in release mode. Sometimes, it is solved by adding a simple line break in the interface and recompiling. But then it happens again, especially when compiling through app center. I am using the latest version of Refit (6.3.2), but sometimes it also happens in applications with version 5.x. What can happen? Attached Stacktrace for Xamarin Android:
```
E android.runtime.JavaProxyThrowable: System.InvalidOperationException: IApiEndpointInterface 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.
E at Refit.RestService.GetGeneratedType (System.Type refitInterfaceType) [0x00024] in <35270eda0328411cb9efadf1bfaeac9f>:0
E at Refit.RestService.For (System.Type refitInterfaceType, System.Net.Http.HttpClient client, Refit.IRequestBuilder builder) [0x00000] in <35270eda0328411cb9efadf1bfaeac9f>:0
E at Refit.RestService.For[T] (System.Net.Http.HttpClient client, Refit.IRequestBuilder`1[T] builder) [0x00000] in <35270eda0328411cb9efadf1bfaeac9f>:0
E at Refit.HttpClientFactoryExtensions+<>c__2`1[T].<AddRefitClient>b__2_3 (System.Net.Http.HttpClient client, System.IServiceProvider serviceProvider) [0x00007] in <27045b5561f1439eb39
751889fd87d7b>:0
E at Microsoft.Extensions.DependencyInjection.HttpClientBuilderExtensions+<>c__DisplayClass18_0`1[TClient].<AddTypedClientCore>b__0 (System.IServiceProvider s) [0x00019] in <dae2b93d46
0143a69fe93cb50ed6a7ed>:0
E at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitFactory (Microsoft.Extensions.DependencyInjection.ServiceLookup.FactoryCallSite factoryCallSite
, Microsoft.Extensions.DependencyInjection.ServiceLookup.RuntimeResolverContext context) [0x0000d] in <4cfecac43588472b828d32265d55bddc>:0
E at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2[TArgument,TResult].VisitCallSiteMain (Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceCallSi
te callSite, TArgument argument) [0x00023] in <4cfecac43588472b828d32265d55bddc>:0
E at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitDisposeCache (Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceCallSite transientC
allSite, Microsoft.Extensions.DependencyInjection.ServiceLookup.RuntimeResolverContext context) [0x00007] in <4cfecac43588472b828d32265d55bddc>:0
E at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2[TArgument,TResult].VisitCallSite (Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceCallSite c
allSite, TArgument argument) [0x00060] in <4cfecac43588472b828d32265d55bddc>:0
E at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.Resolve (Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceCallSite callSite, Microsoft.
Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope scope) [0x00026] in <4cfecac43588472b828d32265d55bddc>:0
E at Microsoft.Extensions.DependencyInjection.ServiceLookup.DynamicServiceProviderEngine+<>c__DisplayClass2_0.<RealizeService>b__0 (Microsoft.Extensions.DependencyInjection.ServiceLook
up.ServiceProviderEngineScope scope) [0x00005] in <4cfecac43588472b828d32265d55bddc>:0
E at Microsoft.Extensions.DependencyInjection.ServiceProvider.GetService (System.Type serviceType, Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope ser
viceProviderEngineScope) [0x00034] in <4cfecac43588472b828d32265d55bddc>:0
E at Microsoft.Extensions.DependencyInjection.ServiceProvider.GetService (System.Type serviceType) [0x00008] in <4cfecac43588472b828d32265d55bddc>:0
E at App.App.OnStart () [0x000ed] in <f387af337cbb4f49a6831dac5f9331f2>:0
E at Xamarin.Forms.Application.SendStart () [0x00000] in <f366f2dcd9cb4bf3980d838b3b188da4>:0
E at Xamarin.Forms.Platform.Android.FormsAppCompatActivity.OnStateChanged () [0x0001b] in <4da67e29198c41db9e82d94eef1969f0>:0
E at Xamarin.Forms.Platform.Android.FormsAppCompatActivity.OnStart () [0x00046] in <4da67e29198c41db9e82d94eef1969f0>:0
E at Android.App.Activity.n_OnStart (System.IntPtr jnienv, System.IntPtr native__this) [0x00008] in <6651ad3ab3a94c7fb62a1d3fe071e339>:0
E at (wrapper dynamic-method) Android.Runtime.DynamicMethodNameCounter.39(intptr,intptr)
E at crc643f46942d9dd1fff9.FormsAppCompatActivity.n_onStart(Native Method)
E at crc643f46942d9dd1fff9.FormsAppCompatActivity.onStart(Unknown Source:0)
E at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1447)
E at android.app.Activity.performStart(Activity.java:8237)
E at android.app.ActivityThread.handleStartActivity(ActivityThread.java:4084)
E at android.app.servertransaction.TransactionExecutor.performLifecycleSequence(TransactionExecutor.java:235)
E at android.app.servertransaction.TransactionExecutor.cycleToPath(TransactionExecutor.java:215)
E at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:187)
E at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:105)
E at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2613)
E at android.os.Handler.dispatchMessage(Handler.java:110)
E at android.os.Looper.loop(Looper.java:219)
E at android.app.ActivityThread.main(ActivityThread.java:8668)
E at java.lang.reflect.Method.invoke(Native Method)
E at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:513)
E at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1109)
Same. Can we trace the generator to diagnose this?
Describe the bug
We've been playing around with generating Refit interfaces using the CodeAnalyzer and so far we've been able to generate an interface that, to us, looks like an interface that Refit would accept. However, we've been unable to register it with Refit since we only get the exception below. ...
@PontusMagnusson, hi, don't know if it is still actual, I got the same error, and in result the problem was in the package versions. Let me describe.
We have external nuget package with client interfaces and main project with reference to this package. When we migrated from Refit 5.4.2
to 6.3.2
, we upgraded both package and main project dependencies, but made a mistake and package still referred to Refit 5.4.2
. This was the main reason of the issue, since new Refit version uses different naming policy for generated client type. When new RestService
looks for client implementation at runtime, it uses the new naming policy, however, the generated class type unique name is created using old policy.
For example if you have type MyNamespace.Clients.IFooClient
which describes API, the unique name will be the following depending on Refit version:
5.4.2: "MyNamespace.Clients.IFooClient.AutoGeneratedIFooClient, MyNamespace, Version=1.0.0, Culture=neutral, PublicKeyToken=null"
6.3.2: "Refit.Implementation.Generated+MyNamespaceClientsIFooClient, MyNamespace, Version=1.0.0, Culture=neutral, PublicKeyToken=null"
When we ensured that our project dependencies refers to the same Refit version, the issue was resolved.
Perhaps you faced completely different issue, but I suppose anyway this is somehow related to the unique name of type the Refit uses.
Hope my comment is informative, since when I was googling it, I didn't find this details and I had to debug it and investigate on my own :).