ASP.NET 核心中的 ILogger 和 DependencyInjection 架构
ILogger and DependencyInjection Architecture in ASP.NET Core
我的团队非常擅长依赖注入。就我个人而言,我最近有点太脱离循环了,无法真正判断这个的正确用法。但我确实看到越来越多这样的代码:
public AuthenticationApi(ILogger<AuthenticationApi> logger,
HttpClient httpClient,
IJsonConverter jsonConverter,
IDtoConverter dtoConverter) : base(logger, httpClient, jsonConverter)
{
_dtoConverter = dtoConverter;
}
然后这在代码中成倍增加,我们一半的代码只是用无穷无尽的方式调用构造函数
DependencyInjection 相关的东西。我的团队告诉我,这就是 .NET Core 的方式。是的,这样的回答证实了这一点:
像这样的讨论更符合我的直觉,我觉得日志记录等应该是透明的,而不是在无休止的 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);
}
}
}
And then this multiplies across the code, where half of our code is just calling constructors with endless DependencyInjection related stuff. My team told me, that's the way of .NET Core.
是也不是。依赖项的构造函数注入是 .NET Core 中组织依赖项的标准方法。而且效果很好。
不标准的是您的基础 class 以及您拥有那些实际上不需要一半参数的构造函数链,而只是进入基础 class 构造函数。我敢打赌,这个基地 class 实际上并没有做任何有价值的事情。
删除基础class。查看每个控制器还需要什么。只注入那个。这些基础 classes 和它们自己的构造函数是 混淆 实际依赖项的好方法。因为现在突然 每个 class 都需要一个 IJsonConverter,一定非常重要。但是您将很难弄清楚 实际上 谁在使用使用它的基本 class 功能。那么在你的 20 个 class 派生自基类中,谁真正需要它,谁只需要它来让编译器开心?
我的建议是删除基础 class。将他们需要的东西注入每个控制器,不多也不少。所以你实际上可以看到 dependencies。如果您在该基础 class 中具有通用功能,它可能是某处获取这些字段作为参数的静态方法。或者它可以是在需要时注入的自己的服务。但是只需要的地方。
我的团队非常擅长依赖注入。就我个人而言,我最近有点太脱离循环了,无法真正判断这个的正确用法。但我确实看到越来越多这样的代码:
public AuthenticationApi(ILogger<AuthenticationApi> logger,
HttpClient httpClient,
IJsonConverter jsonConverter,
IDtoConverter dtoConverter) : base(logger, httpClient, jsonConverter)
{
_dtoConverter = dtoConverter;
}
然后这在代码中成倍增加,我们一半的代码只是用无穷无尽的方式调用构造函数 DependencyInjection 相关的东西。我的团队告诉我,这就是 .NET Core 的方式。是的,这样的回答证实了这一点:
像这样的讨论更符合我的直觉,我觉得日志记录等应该是透明的,而不是在无休止的 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);
}
}
}
And then this multiplies across the code, where half of our code is just calling constructors with endless DependencyInjection related stuff. My team told me, that's the way of .NET Core.
是也不是。依赖项的构造函数注入是 .NET Core 中组织依赖项的标准方法。而且效果很好。
不标准的是您的基础 class 以及您拥有那些实际上不需要一半参数的构造函数链,而只是进入基础 class 构造函数。我敢打赌,这个基地 class 实际上并没有做任何有价值的事情。
删除基础class。查看每个控制器还需要什么。只注入那个。这些基础 classes 和它们自己的构造函数是 混淆 实际依赖项的好方法。因为现在突然 每个 class 都需要一个 IJsonConverter,一定非常重要。但是您将很难弄清楚 实际上 谁在使用使用它的基本 class 功能。那么在你的 20 个 class 派生自基类中,谁真正需要它,谁只需要它来让编译器开心?
我的建议是删除基础 class。将他们需要的东西注入每个控制器,不多也不少。所以你实际上可以看到 dependencies。如果您在该基础 class 中具有通用功能,它可能是某处获取这些字段作为参数的静态方法。或者它可以是在需要时注入的自己的服务。但是只需要的地方。