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

[Feature] Add support for keyed services #1876

Open
bartlomiejgawel opened this issue Oct 11, 2024 · 0 comments
Open

[Feature] Add support for keyed services #1876

bartlomiejgawel opened this issue Oct 11, 2024 · 0 comments

Comments

@bartlomiejgawel
Copy link

Is your feature request related to a problem? Please describe.
It would be useful to register the same API client for multiple accounts. Imagine the following situation:

  • Account A
  • Account B

Based on some data from the request, I would like to be able to select an appropriate account and set a correct Authorization header.

Setting the Authorization header requires obtaining an access token. This logic is already done in the delegating HTTP handler. Unfortunately, the only way to pass some data to that handler (and indicate which account should be used) is to add the Property option, for example:

public interface IClient
{
    [Post("/api/test")]
    Task<Response> DoSomethingAsync([FromBody] Request request, [Property("Account")] string account);
}

If the client has multiple endpoints, it is not a convenient way to do that. We can use keyed services instead.

Describe the solution you'd like
Keyed services were introduced in .NET 8. Instead of using the approach mentioned above, we could do:

services
    .AddRefitClient<IClient>("Account A")
    .ConfigureHttpClient(client =>
        client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", "***")
    );
services
    .AddRefitClient<IClient>("Account B")
    .ConfigureHttpClient(client =>
        client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", "***")
    );

// or
services
    .AddRefitClient<IClient>("Development")
    .ConfigureHttpClient(client => client.BaseAddress = new Uri("https://dev.api.com"));
services
    .AddRefitClient<IClient>("Production")
    .ConfigureHttpClient(client => client.BaseAddress = new Uri("https://prod.api.com"));

// or
services
    .AddRefitClient<IClient>("v1")
    .ConfigureHttpClient(client => client.BaseAddress = new Uri("https://api.com/v1"));
services
    .AddRefitClient<IClient>("v2")
    .ConfigureHttpClient(client => client.BaseAddress = new Uri("https://api.com/v2"));

And later use an IKeyedServiceProvider or IServiceProvider to get the appropriate client:

var client = keyedServiceProvider.GetRequiredKeyedService<IClient>("Account A");

Describe alternatives you've considered
As mentioned above, we can alternatively use the Property option or register Refit clients for different interfaces. However, neither of these approaches is convenient.

Describe suggestions on how to achieve the feature
Maybe adding an API for .NET 8 and greater to register keyed Refit clients could solve that issue.

Additional context
Feel free to suggest other ideas 🙂

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant