Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG] AddRefitClient non-generic version does not register service #745

Closed
holotrek opened this issue Sep 12, 2019 · 7 comments
Closed

[BUG] AddRefitClient non-generic version does not register service #745

holotrek opened this issue Sep 12, 2019 · 7 comments
Labels

Comments

@holotrek
Copy link

Describe the bug

When registering the refit client with the HttpClientFactoryExtensions using the method overload that takes in a runtime type (i.e. services.AddRefitClient(myInterfaceType, settings)), the service is not registered as it is with the generic version. This is due to it missing the line services.AddSingleton(provider => RequestBuilder.ForType(refitInterfaceType, settings)); similar to the way it does it in the first line of the generic method, located here.

Steps To Reproduce

  1. Create standard Refit interface, i.e. IMyApi
  2. Create a .net core web API
  3. In Startup.ConfigureServices, get a Type for your interface type and call the broken AddRefitClient method:
var refitInterfaceType = typeof(IMyApi);
services.AddRefitClient(refitInterfaceType);
  1. In a controller, inject the IMyApi and attempt to use it in an endpoint:
[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
{
  private readonly IMyApi _api;
  public ValuesController(IMyApi api)
  {
    _api = api;
  }

  // GET api/values
  [HttpGet]
  public ActionResult<IEnumerable<string>> Get()
  {
    _api.GetThing();
    return new string[] { "value1", "value2" };
  }
}
  1. Navigate to route and receive error like InvalidOperationException: Unable to resolve service for type 'IMyApi' while attempting to activate 'test_api.Controllers.ValuesController'.
  2. Note: follow steps 1-4 and use the generic version to register the API and it will work:
    services.AddRefitClient<IMyApi>();

Expected behavior

It is expected that adding the refit client with the runtime type will act the same as adding it with the generic type.

Environment

  • OS: Windows 10
  • Version: 4.7.9
  • Device: Desktop
@holotrek holotrek added the bug label Sep 12, 2019
@lobster2012-user
Copy link

lobster2012-user commented Sep 15, 2019

It looks like a bug.
https://github.com/reactiveui/refit/blob/master/Refit.HttpClientFactory/HttpClientFactoryExtensions.cs

You can do PR with tests.

GitHub
The automatic type-safe REST library for .NET Core, Xamarin and .NET. Heavily inspired by Square's Retrofit library, Refit turns your REST API into a live interface. - reactiveui/refit

@362486122
Copy link

362486122 commented Sep 19, 2019

I also got this problem.here is my solution.

  1. Because of the IHttpClientBuilder don't have a matched method.
public static IHttpClientBuilder AddTypedClient(this IHttpClientBuilder builder, Type type, Func<HttpClient, IServiceProvider, object> factory)
        {
            if (builder == null)
            {
                throw new ArgumentNullException(nameof(builder));
            }

            if (factory == null)
            {
                throw new ArgumentNullException(nameof(factory));
            }

            builder.Services.AddTransient(type, s =>
            {
                var httpClientFactory = s.GetRequiredService<IHttpClientFactory>();
                var httpClient = httpClientFactory.CreateClient(builder.Name);

                return factory(httpClient, s);
            });

            return builder;
        }
  1. Add a new AddRefitClient method
public static IHttpClientBuilder AddRefitClient(this IServiceCollection services, Type refitInterfaceType, RefitSettings settings = null)
        {
            return services.AddHttpClient(UniqueName.ForType(refitInterfaceType))
                           .AddTypedClient(refitInterfaceType, (client, serviceProvider) => RestService.For(refitInterfaceType, client, settings));
        }

@Davilink
Copy link

Davilink commented Nov 19, 2019

We had a similar problem, refit tried to register all the typeclient under the same name, so the DI container was throwing exception (this type is already registred...). We created this workaround :

public static class IServiceCollectionExtension
    {
        public static IServiceCollection AddRestServiceClient(this IServiceCollection services, Type type, Action<IServiceProvider, HttpClient> clientFactory)
        {
            services.AddHttpClient(type.FullName, clientFactory)
                .Services.AddTransient(type, services =>
                {
                    var httpClientFactory = services.GetRequiredService<IHttpClientFactory>();
                    var httpClient = httpClientFactory.CreateClient(type.FullName);
                    return Refit.RestService.For(type, httpClient);
                });

            return services;
        }

        public static IServiceCollection AddRestServiceClient(this IServiceCollection services, Type type, Action<HttpClient> clientFactory)
        {
            return AddRestServiceClient(services, type, (serviceProvider, client) => clientFactory(client));
        }
    }

I think the problem seem to be around the UniqueName.ForType

@mingyangzhu
Copy link

+1 me too.

JeremyBP added a commit to Respawnsive/refit that referenced this issue May 13, 2020
@JeremyBP JeremyBP mentioned this issue May 13, 2020
2 tasks
clairernovotny added a commit that referenced this issue May 19, 2020
@CooperLiu
Copy link

is it released?

@clairernovotny
Copy link
Member

Closing due to age. Please try Refit v6 and reopen if still an issue.

@github-actions
Copy link

This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Apr 13, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

7 participants