-
Notifications
You must be signed in to change notification settings - Fork 35
Expand file tree
/
Copy pathHttpClientRegistrator.cs
More file actions
149 lines (128 loc) · 4.39 KB
/
HttpClientRegistrator.cs
File metadata and controls
149 lines (128 loc) · 4.39 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Polly;
using ViennaNET.Utils;
namespace ViennaNET.HttpClient
{
/// <summary>
/// Класс-строитель для создания и регистрации Http-клиентов в стандартном DI
/// </summary>
public class HttpClientRegistrator
{
private const int defaultTimeout = 30;
private readonly List<Action<IServiceCollection, IHttpClientBuilder>> _addHandlerActions;
private Action<IHttpClientBuilder> _configureBuilderAction;
protected HttpClientRegistrator()
{
_addHandlerActions = new List<Action<IServiceCollection, IHttpClientBuilder>>();
}
protected string _url { get; set; }
protected string _name { get; set; }
private int? _secondsTimeout { get; set; }
/// <summary>
/// Создает экземпляр данного регистратора
/// </summary>
/// <returns></returns>
public static HttpClientRegistrator Create()
{
return new();
}
/// <summary>
/// Устанавливает базовый адрес
/// </summary>
/// <param name="url"></param>
/// <returns></returns>
public HttpClientRegistrator WithUrl(string url)
{
_url = url;
return this;
}
/// <summary>
/// Задает имя клиента. Должно быть уникально
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
public HttpClientRegistrator WithName(string name)
{
_name = name;
return this;
}
/// <summary>
/// Устанавливает таймаут. По-умолчанию 30 секунд
/// </summary>
/// <param name="secondsTimeout"></param>
/// <returns></returns>
public HttpClientRegistrator WithTimeout(int? secondsTimeout)
{
_secondsTimeout = secondsTimeout;
return this;
}
/// <summary>
/// Регистрирует стандартное middleware, без привязки к стороннему контейнеру
/// </summary>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public HttpClientRegistrator WithHandler<T>() where T : DelegatingHandler
{
_addHandlerActions.Add((services, clientBuilder) =>
{
services.TryAddTransient<T>();
clientBuilder.AddHttpMessageHandler<T>();
});
return this;
}
/// <summary>
/// Регистрирует стандартное middleware, без привязки к стороннему контейнеру
/// </summary>
public HttpClientRegistrator WithHandler<T>(Func<T> configureHandler) where T : DelegatingHandler
{
_addHandlerActions.Add((services, clientBuilder) =>
{
clientBuilder.AddHttpMessageHandler(configureHandler);
});
return this;
}
/// <summary>
/// Дополнительно конфигурирует билдер Http-клиентов
/// </summary>
/// <typeparam name="T"></typeparam>
public HttpClientRegistrator ConfigureBuilder(Action<IHttpClientBuilder> builderAction)
{
_configureBuilderAction = builderAction;
return this;
}
/// <summary>
/// Завершает регистрацию Http-клиента в приложении AspNetCore
/// </summary>
/// <param name="services"></param>
public void Register(IServiceCollection services)
{
ValidateClientBuilder();
var baseBuilder = BuildBaseHttpClient(services);
foreach (var handlerAction in _addHandlerActions)
{
handlerAction(services, baseBuilder);
}
}
private IHttpClientBuilder BuildBaseHttpClient(IServiceCollection services)
{
var builder = services.AddHttpClient(_name, client =>
{
client.BaseAddress = new Uri(_url);
client.Timeout = TimeSpan.FromSeconds(_secondsTimeout ?? defaultTimeout);
});
_configureBuilderAction?.Invoke(builder);
builder.AddTransientHttpErrorPolicy(p => p.WaitAndRetryAsync(Enumerable.Repeat(TimeSpan.FromSeconds(1), 3)));
return builder;
}
private void ValidateClientBuilder()
{
_name.ThrowIfNull("httpClient.Name");
_url.ThrowIfNull("httpClient.Url");
}
}
}