【发布时间】:2021-05-18 12:16:52
【问题描述】:
我的团队非常依赖 DependencyInjection。就个人而言,我最近有点离题太远了,无法真正判断这个的正确用法。但我确实看到越来越多这样的代码:
public AuthenticationApi(ILogger<AuthenticationApi> logger,
HttpClient httpClient,
IJsonConverter jsonConverter,
IDtoConverter dtoConverter) : base(logger, httpClient, jsonConverter)
{
_dtoConverter = dtoConverter;
}
然后这会在代码中成倍增加,我们一半的代码只是在无限调用构造函数 DependencyInjection 相关的东西。我的团队告诉我,这就是 .NET Core 的方式。是的,这样的答案证实了这一点:
ILogger and DependencyInjection in ASP.NET Core 2+
这样的讨论更符合我的直觉,即日志记录等事情应该是透明的,而不是在无休止的 DependencyInjection 构造函数链中处理:
在另一个地方(不幸的是,我再也找不到这篇文章了),我读到这个构造函数问题主要是由于服务工厂实现不当造成的。
赞赏有关该主题的想法。
根据下面的讨论,这是基类,同时使用 Logger 和 HttpClient:
internal class ApiBase
{
private readonly ILogger _logger;
private readonly IJsonConverter _jsonConverter;
private readonly HttpClient _httpClient;
public ApiBase(ILogger logger, HttpClient httpClient, IJsonConverter jsonConverter)
{
_logger = logger;
_jsonConverter = jsonConverter;
_httpClient = httpClient;
}
protected async Task<T> GetAsync<T>(string path, HttpContent content = null)
{
_logger.LogDebug($"Sending GET request to {path}");
using (var request = new HttpRequestMessage(HttpMethod.Get, path))
{
request.Content = content;
using (var response = await _httpClient.SendAsync(request).ConfigureAwait(false))
{
if (response.IsSuccessStatusCode)
{
_logger.LogDebug($"GET request to {path} was successful.");
var responseContent = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
var deserializeResponseContent = _jsonConverter.Deserialize<T>(responseContent);
return deserializeResponseContent;
}
var message = GetErrorMessage("GET", path, response);
_logger.LogError(message);
throw new HttpRequestException(message);
}
}
}
【问题讨论】:
-
不,这根本不是 .NET Core 的方式。也没有涉及到服务工厂——那些构造函数对它们的参数是如何创建的一无所知。无论您使用构造函数或参数注入,还是根本不使用注入,您总会遇到方法参数过多的情况。典型的解决方案是创建一个参数对象,结合常见的依赖关系。
-
至于
HttpClient,除非您在 Blazor WASM 中编写 SPA,否则您可能永远不会只使用HttpClient。在任何其他情况下,您将需要调用多个远程服务,因此您将拥有具有自己的 cookie、身份验证、重试策略的类型化类,而不是单个 HttpClient。一些依赖关系非常普遍,因此创建一个context类来组合它们并将其传递到任何地方可能是有意义的。 -
至于其他两个转换器……嗯?这些东西是干什么用的?您是否打算即时从 System.Text.Json 切换到 Json.NET?那有什么意义呢?如果你想使用 AutoMapper,你可以注入一个 IMapper 实例,而不是把它包装在另一个接口中,以防你决定切换映射库
-
那么,我猜你是作者之一,@Steven?
-
@Fildor:是的,我认为这很清楚 ;-)
标签: c# .net-core dependency-injection