Coding Stephan

Kiota with dependency injection

Kiota is an open-source application that allows you to generate a client for any api that is documented with open api. It’s a great tool and we use it for all our new projects where we call an api. What we also use in all our applications is dependency injection, and those two need to be combined to get the best performance and most stable application.

Kiota Dependency Injection

Why use dependency injection?

Dependency injection is a way to make your application more testable, maintainable, and scalable. It allows you to inject the dependencies into your classes, instead of creating them in the class. This way, you can easily replace the implementation of a class with another one, without changing the class itself. This is especially useful when you want to test your application, as you can easily mock the dependencies.

In our opinion this is not the only reason to use dependency injection. The dotnet team has put a lot of effort into managing HttpClients, especially reusing the tcp connections that are used by those clients. If you don’t manage them correctly, you’re going to run out of them and your application might stop responding to http requests because it cannot create any new sockets. Before the Microsoft.Extensions.Http package, you had to manage this yourself, but now it’s all done for you.

Kiota with dependency injection the wrong way

Create a service that creates a client using the injected HttpClient, and use that client to call the api.

public class MyService
{
    private readonly GraphServiceClient _graphClient;

    public MyService(HttpClient client)
    {
        IAuthenticationProvider authProvider = new SomeCustomAuthenticationProvider(...);
        _graphClient = new GraphServiceClient(new HttpClientRequestAdapter(authProvider, httpClient: client));
    }
}

And register the service in the Startup.cs file, using the AddHttpClient method.

// This will configure a named http client and register the MyService class as a service.
services.AddHttpClient<MyService>();

In contrast of what I suggested in the title, this will work, but you loose all the nice options that Kiota has to offer. Kiota has several http handlers, that handle additional stuff. For example, the RetryHandler will retry the request if it fails, and the RedirectHandler will follow the redirect. If you use the HttpClient directly, you loose all those features.

Kiota handlers?

I figured out the code above didn’t work the hard way. I wanted to use the HeaderInspectionHandler only to figure out that it wasn’t called automatically. I had to dive into the source code of Kiota to figure out why it wasn’t working. And in the end, it was pretty obvious, I had not registered them.

Registering the HeaderInspectionHandler?

The trick I had to figure out was, how do I get the official handlers connected to my http client that is managed by the HttpClientFactory. You need to register them in your service provider services.AddTransient(handler), and then connect them to the HttpClient using the AddHttpMessageHandler method.

services.AddTransient<HeadersInspectionHandler>();
....

services.AddHttpClient<MyService>()
  .AddHttpMessageHandler<HeadersInspectionHandler>();

Registering all handlers?

This worked for me, but is not very sustainable. By default Kiota uses 6 handlers (at this moment), and you have to register them all manually. You could not easily get a list of default handlers, so I created a pull request to add a method to get the default handlers. You can now enumerate over the default handlers and register them all in one go.

// Dynamically load the Kiota handlers from the Client Factory
var kiotaHandlers = KiotaClientFactory.GetDefaultHandlerTypes();
// And register them in the DI container
foreach(var handler in kiotaHandlers)
{
    services.AddTransient(handler);
}

You can also use the same list to connect them to your HttpClient.

var httpClientBuilder = services.AddHttpClient<MyService>();
foreach(var handler in kiotaHandlers)
{
    httpClientBuilder.AddHttpMessageHandler((sp) => (DelegatingHandler)sp.GetRequiredService(handler));
}

I jumped through the hoops for you

I can imagine that I’m not the only one who wants to use Kiota with dependency injection, so I created a pull request to add a page to learn.microsoft.com. I’m not going to repeat the code here, just check out the official docs (written by me 🤩).

Seeing a page I wrote on the official docs really makes me proud, I’ll try to contribute more to this community in the future.

You can also check-out the working sample in the Kiota samples repository.

Writing docs

Writing good documentation that suites everyone is super difficult. Being able to share this knowledge with the community is a great feeling. I hope this will help you in your journey to use Kiota with dependency injection.

Conclusion

Wether or not you’re going to use Kiota with dependency injection, just make sure you don’t run out of tcp connections. Another reason why you would want to use the HttpClientFactory with Kiota, is that the default handlers created by Kiota don’t work in a Blazor wasm application, which I figured out some time ago. If you have any questions, feel free to reach out to me on Twitter or LinkedIn.