refit icon indicating copy to clipboard operation
refit copied to clipboard

[Bug]: Refit.IRequestBuilder Dependency Injection Throws Exception

Open HamidMusayev opened this issue 1 year ago • 4 comments

Refit.IRequestBuilder dependency injection exception 🐞

Interface

public interface IPetStoreClient
{
    [Post("/store/order")]
    Task<Order> PlaceOrder([Body] Order body);

    [Get("/store/order/{orderId}")]
    Task<Order> GetOrderById(long orderId);

    [Delete("/store/order/{orderId}")]
    Task DeleteOrder(long orderId);
}

Exception An unhandled exception of type 'System.AggregateException' occurred in Microsoft.Extensions.DependencyInjection.dll: 'Some services are not able to be constructed' Inner exceptions found, see $exception in variables window for more details. Innermost exception System.InvalidOperationException : Unable to resolve service for type 'Refit.IRequestBuilder' while attempting to activate 'Refit.Implementation.Generated+BLLExternalClientsIPetStoreClient'.

Injection

builder.Services
            .AddRefitClient<IPetStoreClient>()
            .ConfigureHttpClient(c => c.BaseAddress = new Uri(config.PetStoreClientSettings.BaseUrl));

Usage

public class HelperController : Controller
{
    private readonly IPetStoreClient _petStoreClient;

    public HelperController(IPetStoreClient petStoreClient)
    {
        _petStoreClient = petStoreClient;
    }

    [HttpGet("test")]
    public async Task<IActionResult> Get()
    {
        var response = await _petStoreClient.GetOrderById(24);
        return Ok(response);
    }
}

Note 1 Same error when creating inside constructor

public class TestController : Controller
{
  private readonly IPetStoreClient _petStoreClient;

  public HelperController(ConfigSettings configSettings)
  {
      _petStoreClient = RestService.For<IPetStoreClient>(configSettings.PetStoreClientSettings.BaseUrl);
  }

Note 2 Same error when creating instance

[HttpGet("test")]
    public async Task<IActionResult> Get()
    {
        var client = RestService.For<IPetStoreClient>(_configSettings.PetStoreClientSettings.BaseUrl);
        var response = await client.GetOrderById(24);

        return Ok(response);
    }

Step to reproduce

Refit.HttpClientFactory v7.0.0 Refit v7.0.0

Reproduction repository

https://github.com/reactiveui/refit

Expected behavior

Dependency injection IRequestBuilder exception

Screenshots 🖼️

No response

IDE

Visual Studio 2022, Rider Windows, Visual Studio Code

Operating system

Windows

Version

No response

Device

No response

Refit Version

7.0.0

Additional information ℹ️

null

HamidMusayev avatar Oct 20 '23 14:10 HamidMusayev

Update: Moving refit interfaces to another project inside solution fixes the bug

HamidMusayev avatar Nov 07 '23 21:11 HamidMusayev

Update: Moving refit interfaces to another project inside solution fixes the bug

@HamidMusayev could you please explain further what made it work? I have the same issue and wonder what the requirement is for the project that should contain the interfaces?

hansmbakker avatar Jul 31 '24 11:07 hansmbakker

I had this issue when using Scrutor. If you are registering dependencies by automatically scanning the assembly, be sure to exclude your refit interface, in your case IPetStoreClient.

Potential cause: .net will validate the dependencies registered can be resolved on application start, meaning your refit interfaces (like IRequestBuilder) have no implementations registered, causing the above exception.

radupurdea avatar Aug 07 '24 17:08 radupurdea

I had this issue when using Scrutor.

Yes, we're using Scrutor too.

hansmbakker avatar Aug 16 '24 13:08 hansmbakker