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

Document recommended DI usage #481

Open
aradalvand opened this issue Sep 26, 2023 · 2 comments
Open

Document recommended DI usage #481

aradalvand opened this issue Sep 26, 2023 · 2 comments

Comments

@aradalvand
Copy link

aradalvand commented Sep 26, 2023

What is the optimal way of using MeilisearchClient with ASP.NET Core's DI container? It would be helpful if this was documented, or even better, if the library shipped with extension methods on IServiceCollection (e.g. AddMeilisearchClient).

It's also a bit tricky to use MeilisearchClient with .AddHttpClient, since you also need to pass the apiKey through the constructor. Currently, I have had to do this:

builder.Services.AddHttpClient(nameof(MeilisearchClient), client =>
{
    client.BaseAddress = new("<server-url>");
}).AddTypedClient<MeilisearchClient>(client => new(
    client,
    "<api-key>"
));

Update: I just found out that using the constructor that receives an HttpClient means the MeilisearchMessageHandler won't be registered on the client, and consequently, Meilisearch-specific exceptions like MeilisearchApiError won't be thrown.
This is problematic and really confusing. This area is in dire need of some refinement.

@aradalvand aradalvand changed the title Document DI usage Document recommended DI usage Sep 26, 2023
@brunoocasali
Copy link
Member

@ahmednfwela could I have your opinion on this case? I personally never used DI on C#

@ahmednfwela
Copy link
Collaborator

ahmednfwela commented Oct 18, 2023

First I like to store all meilisearch related configs in a separate class

public class MeilisearchConfig
{
    public string Url { get; set; }
    public string ApiKey { get; set; }
}

Then, configuring the services

var hostBuilder = Host.CreateDefaultBuilder(args)
            .ConfigureServices((context, services) =>
            {   
                // Configure meilisearch settings (either in code or via configuration).
                // Option 1
                // IConfiguration meilisearchConfig = context.Configuration.GetRequiredSection("meilisearch");
                // services.Configure<MeilisearchConfig>(meilisearchConfig);
                // Option 2
                services.Configure<MeilisearchConfig>((config) =>
                {
                    config.Url = "http://localhost:7700";
                    config.ApiKey = "masterKey";
                });

                // Add MeilisearchMessageHandler
                services.AddTransient<MeilisearchMessageHandler>();

                // Add a named HttpClient for MeilisearchClient.             
                services.AddHttpClient(nameof(MeilisearchClient), (sp, client) =>
                {
                    var config = sp.GetRequiredService<IOptions<MeilisearchConfig>>().Value;
                    //configure the http client
                    client.BaseAddress = new Uri(config.Url);
                }).AddTypedClient<MeilisearchClient>((client, sp) =>
                {
                    var config = sp.GetRequiredService<IOptions<MeilisearchConfig>>().Value;
                    return new MeilisearchClient(client, config.ApiKey);
                }).AddHttpMessageHandler<MeilisearchMessageHandler>();
            });

meili-bors bot added a commit that referenced this issue Oct 25, 2023
493: Simplify construction of MeilisearchClient in DI r=ahmednfwela a=ahmednfwela

# Pull Request

## Related issue
Fixes part of #481, which is the inability to use `.AddHttpMessageHandler<MeilisearchMessageHandler>()`

## What does this PR do?
- Adds default constructor for `MeilisearchMessageHandler`
- Refactor `MeilisearchClient` constructors to call one another, instead of redefining the logic in both.

## PR checklist
Please check if your PR fulfills the following requirements:
- [x] Does this PR fix an existing issue, or have you listed the changes applied in the PR description (and why they are needed)?
- [x] Have you read the contributing guidelines?
- [x] Have you made sure that the title is accurate and descriptive of the changes?

Thank you so much for contributing to Meilisearch!


Co-authored-by: Ahmed Fwela <[email protected]>
Co-authored-by: Ahmed Fwela <[email protected]>
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

3 participants