问题
How can I set a default value to a property, reading it from my appsettings.json file, on a model that is instantiated by the .NET Core 3 framework?
I've created a repo (a completely new .NET Core 3 project) where I try to illustrate the problem: https://github.com/NelsonPRSousa/dependency-injection-default-constructor
API Action:
[HttpGet]
public IEnumerable<WeatherForecast> Get([FromQuery] FilteringRequestModel request)
{
var defaultType = request.Type;
var rng = new Random();
return Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
Date = DateTime.Now.AddDays(index),
TemperatureC = rng.Next(-20, 55),
Summary = Summaries[rng.Next(Summaries.Length)]
})
.ToArray();
}
Model:
public class FilteringRequestModel
{
/* Please note that we must have a parameterless constructor, since it's the framework responsability to instatiate this object
* when invoking this action: IEnumerable<WeatherForecast> Get([FromQuery] FilteringRequestModel request)
*/
public FilteringRequestModel()
{
//Type = System.Configuration.ConfigurationManager.AppSettings["DefaultTypeTopRated"];
}
public string Type { get; set; } = "top_rated"; // TODO: Read from appsettings
}
回答1:
You could use IOptions with Dependecy Injection
Update FilteringRequestModel
class
public class FilteringRequestModel
{
public FilteringRequestModel()
{
}
public void Initialize(IOptions<FilteringRequestSettings> settings)
{
if (string.IsNullOrEmpty(this.Type))
{
this.Type = settings.Value.Type;
}
}
public string Type { get; set; }
}
Add a FilteringRequestSettings
class
public class FilteringRequestSettings
{
public string Type { get; set; }
}
Update appsettings.Development.json
like this
{
"Logging": {
"LogLevel": {
"Default": "Debug",
"System": "Information",
"Microsoft": "Information"
}
},
"FilteringRequest": {
"Type": "foo"
}
}
Update ConfigureServices
method in Startup
class like this
public void ConfigureServices(IServiceCollection services)
{
services.Configure<FilteringRequestSettings>(this.Configuration.GetSection("FilteringRequest"));
services.AddControllers();
}
Finally, update WeatherForecastController
class like this
[HttpGet]
public IEnumerable<WeatherForecast> Get([FromQuery] FilteringRequestModel request)
{
request.Initialize(_settings);
var defaultType = request.Type;
var rng = new Random();
return Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
Date = DateTime.Now.AddDays(index),
TemperatureC = rng.Next(-20, 55),
Summary = Summaries[rng.Next(Summaries.Length)]
})
.ToArray();
}
Explanation
- You will load parameter from appsettings into
IOptions<FilteringRequestSettings>
IOptions<FilteringRequestSettings>
will be injected intoWeatherForecastController
- You will then call the
Initialize
method yourrequest
parameter withIOptions<FilteringRequestSettings>
- The
Initialize
method verify if theType
property has not already been set (from query / request). If not, it will use the value from appsettings (throughIOptions<FilteringRequestSettings>
来源:https://stackoverflow.com/questions/58402907/how-to-set-a-default-value-from-appsettings-to-a-property-on-a-api-model