在 .Net 6 中获取设置数据,我使用
IConfiguration 接口,并添加了一些抽象来帮助我在项目中进行测试,使我的代码更加灵活。
例如,在 appsettings.json 文件中有一些 API Url。
"ApiBaseUri": "https://dev.api.com/"
为了尽量减少由于下一个版本的.Net Core框架中与配置文件处理机制的变化而导致的代码更改成本,我使用了一个对接口进行封装的包装器。
public interface IConfigurationWrapper
{
string? GetSectionValue(string key);
}
public class ConfigurationWrapper : IConfigurationWrapper
{
private readonly IConfiguration _config;
public ConfigurationWrapper(IConfiguration config)
{
_config = config;
}
public string? GetSectionValue(string key)
{
return _config.GetSection(key).Value;
}
}
最后,还有一个特殊的界面来表示配置文件中的设置:
public interface IAppSettings
{
Uri? GetApiBaseUri();
}
public class AppSettings : IAppSettings
{
private const string ApiBaseUriSettingName = "ApiBaseUri";
private readonly IConfigurationWrapper _config;
public AppSettings(IConfigurationWrapper config)
{
_config = config;
}
public Uri? GetApiBaseUri()
{
string uriValue = _config.GetSectionValue(ApiBaseUriSettingName);
return string.IsNullOrEmpty(uriValue) ? null : new Uri(uriValue);
}
}
这就是我在代码中使用它的方式:
public class MyService : IMyService
{
private readonly IAppSettings _settings;
private readonly IRestRequestFactory _requestFactory;
private readonly IRestResponseFactory _responseFactory;
public MyService(IAppSettings settings, IRestRequestFactory requestFactory, IRestResponseFactory responseFactory)
{
_settings = settings;
_requestFactory = requestFactory;
_responseFactory = responseFactory;
}
public async Task<decimal?> GetSomeEndpointResponseAsync(FilterModel filter, CancellationToken token)
{
var request = _requestFactory.CreatePostRequest(ApiUrls.SomeEndpoint, filter);
var response = await _responseFactory.GetRestResponseAsync<ResponseResultModel<decimal?>>(request, _settings.GetApiBaseUri(), token);
return response.Data?.Data;
}
}
而且我还可以轻松地用单元测试覆盖我的
AppSettings
:
[TestFixture]
public class AppSettingsTests
{
private Mock<IConfigurationWrapper> _configurationMock;
private IAppSettings _settings;
[SetUp]
public void SetUp()
{
_configurationMock = new Mock<IConfigurationWrapper>();
_settings = new AppSettings(_configurationMock.Object);
}
[Test]
public void GetApiBaseUri_ApiBaseUriIsEmptyString_ReturnsNull()
{
string uri = string.Empty;
_configurationMock.Setup(m => m.GetSectionValue(It.IsAny<string>())).Returns(uri);
Uri? result = _settings.GetApiBaseUri();
Assert.IsNull(result);
}
[Test]
public void GetApiBaseUri_ApiBaseUriIsNull_ReturnsNull()
{
string uri = null;
_configurationMock.Setup(m => m.GetSectionValue(It.IsAny<string>())).Returns(uri);
Uri? result = _settings.GetApiBaseUri();
Assert.IsNull(result);
}
}
希望这能有所帮助。