Настройка HttpClient с использованием внедрения зависимостей, когда одному клиенту нужна информация от другого - PullRequest
0 голосов
/ 23 июня 2019

У меня есть консольное приложение .NET Core 3.0 (хотя позже я планирую изменить его на приложение Blazor).

В методе public static void Main моего класса Программы я настраиваю внедрение зависимости с помощью шаблонаописанный Microsoft здесь .

В частности, я хочу зарегистрировать несколько HttpClient экземпляров, используя шаблон "именованных клиентов", описанный здесь .

Все нормально, за исключением одной проблемы: у моего второго и третьего экземпляров HttpClient должен быть DefaultRequestHeader, который передает идентификатор сеанса.Но я не буду знать значение идентификатора сеанса, пока не выполню команду API для входа на удаленный сервер, используя первый экземпляр HttpClient.Что мне делать?

Мой код ниже.

Могу ли я как-нибудь получить ссылку на первый экземпляр HttpClient и вызвать мой метод Login из этого блока кода?Или я могу позже вызвать метод Login из другого блока кода, а затем добавить соответствующие DefaultRequestHeader к другим HttpClient экземплярам спустя долгое время после их создания?

public class Program
{
    public static void Main()
    {
        var builder = new ConfigurationBuilder()
            .SetBasePath(Directory.GetCurrentDirectory())
            .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
            .AddUserSecrets<Program>()
            .AddEnvironmentVariables(); ;

        IConfigurationRoot configuration = builder.Build();
        var settings = new ApplicationOptions();
        configuration.GetSection("AppSettings").Bind(settings);

        var services = new ServiceCollection();

        // This is the client I'll use to log in and get a session token
        services.AddHttpClient("Authentication", c =>
        {
            c.BaseAddress = new Uri(settings.AuthenticationApi);
            c.DefaultRequestHeaders.Accept.Clear();
            c.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
            c.DefaultRequestHeaders.Add("X-Application", settings.AppKey);
            c.DefaultRequestHeaders.Add("User-Agent", "My API Client v0.0.1");
        }).ConfigurePrimaryHttpMessageHandler(() =>
        {
            return GetMessageHandlerWithSecurityCertificate(settings);
        });


        // and this is the next of several clients where I'll need to send the session token with my requests
        services.AddHttpClient("AnotherApi", c =>
        {
            c.BaseAddress = new Uri(settings.AnotherApi);
            c.DefaultRequestHeaders.Accept.Clear();
            c.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
            c.DefaultRequestHeaders.Add("X-Application", settings.AppKey);
            c.DefaultRequestHeaders.Add("User-Agent", "My API Client v0.0.1");
            //c.DefaultRequestHeaders.Add("ssoid", sessionToken);
            // What should I do here? I want to add a sessionToken string but I can only get the token's value by using the other HttpClient (above) to log in! 
        });


        // Removed one more HttpClient for brevity
    }

    private static HttpMessageHandler GetMessageHandlerWithSecurityCertificate(ApplicationOptions settings)
    {
        var handler = new HttpClientHandler();
        handler.ClientCertificates.Add(GetSecurityCertificate(settings.SslCertificateFilename, settings.SslCertificatePassword));
        return handler;
    }


    private static X509Certificate2 GetSecurityCertificate(string certFilename, string certPassword)
    {
        return new X509Certificate2(certFilename, certPassword);
    }
}

1 Ответ

0 голосов
/ 23 июня 2019

Разве вы не можете использовать IHttpClientFactory напрямую и генерировать HttpClient в тот момент, когда вам это нужно, используя свои учетные данные?Другими словами, вместо того, чтобы пытаться зарегистрировать все отдельные HttpClient (ы), зарегистрируйте IHttpClientFactory как обычно.Вставить это в класс, который будет нуждаться в HttpClient, и просто создать его с вашими учетными данными там?Вот что я бы сделал.В конце концов, IHttpClientFactory - это просто класс-оболочка, который генерирует ваши HttpClients с использованием фабричного шаблона.

Дополнительно: вы можете использовать метод расширения, чтобы сконфигурировать ваш HttpClient с предустановленными значениями, чтобы сохранить дублирующий код везде для согласованностипрочее.

...