Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dependency injection for DelegatingHandler with multiple constructor parameters and options

I'm trying to use dependency injection for a DelegatingHandler that holds 2 interfaces and 1 string.

public class MessageHandler : DelegatingHandler
{
    private readonly ILogger<MessageHandler> _logger;
    private readonly ISomeService _someService;
    public string Name { get; set; }

    public MessageHandler(ILogger<MessageHandler> logger, ISomeService someService)
    {
        _logger = logger;
        _someService = someService;
    }

    protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request,
        CancellationToken cancellationToken)
    {
        Console.WriteLine($"Doing some other logic with {Name}");
        var response = await base.SendAsync(request, cancellationToken);

        _someService.DoSomething(Name);
        return response;
    }
}

I am adding this DelegatingHandler to an HttpClient via IHttpClientFactory

services.AddHttpClient("github")
    .ConfigureHttpClient(c => { c.BaseAddress = new Uri("https://www.github.com"); })
    .AddHttpMessageHandler<MessageHandler>(); // I want Name property to be 'github'

However I also want to use the MessageHandler with multiple HttpClient with different Names

services.AddHttpClient("twitter")
    .ConfigureHttpClient(c => { c.BaseAddress = new Uri("https://www.twitter.com"); })
    .AddHttpMessageHandler<MessageHandler>(); // I want Name property to be 'twitter'

Is there a way to achieve this without doing:

services.AddHttpClient("github")
    .ConfigureHttpClient(c => { c.BaseAddress = new Uri("https://www.github.com"); })
    .AddHttpMessageHandler(provider =>
    {
        var logger = provider.GetRequiredService<ILogger<MessageHandler>>();
        var someService = provider.GetRequiredService<ISomeService>();
        return new MessageHandler(logger, someService, "github");
    });
like image 573
MrHungrayMan Avatar asked Jun 17 '26 05:06

MrHungrayMan


1 Answers

Given that the original example has the following constructor

public MessageHandler(ILogger<MessageHandler> logger, ISomeService someService)
{
    _logger = logger;
    _someService = someService;
}

You could just resolve the handler and then set the property

services.AddTransient<MessageHandler>();
services.AddHttpClient("github")
    .ConfigureHttpClient(c => { c.BaseAddress = new Uri("https://www.github.com"); })
    .AddHttpMessageHandler(provider => {
        var handler = provider.GetRequiredService<MessageHandler>();
        handler.Name = "github";
        return handler;
    });

Either way you would need to manually resolve the handler to be able to set that string property.

like image 138
Nkosi Avatar answered Jun 18 '26 19:06

Nkosi



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!