Configuration file is the most basic and indispensable part of each project, such as common configurations such as database connection and middleware properties.
The main content of today’s article is in Net core project how to read configuration files and use them.
Prepare in advance
appsettings. JSON file
{
"User": {
"Username": "Zhao Yi",
"userAge": 18
}
}
Corresponding entity model
public class UserOption
{
public string userName { get; set; }
public int userAge { get; set; }
}
General read
1. Register
Registering in the startup class mainly uses the configure method:
services.Configure<UserOption>(Configuration.GetSection("User"));
2. Inject and read in the controller
public class HomeController : ControllerBase
{
private readonly UserOption user;
public HomeController(IOptions<UserOption> userOptions)
{
user = userOptions.Value;
}
[HttpGet]
public string Get()
{
Return $"Name: {user. Username}, age: {user. Userage}";
}
}
Output result:Name: Zhao Yi, age: 18
Nested read
We are interested in Appsettings JSON file to make a small change, add a child nodechild
:
{
"User": {
"Username": "Zhao Yi",
"userAge": 18,
"child": {
"Username": "Zhao Yi's cub",
"userAge": 2
}
}
}
Make a small change to the registered code:
services.Configure<UserOption>(Configuration.GetSection("User:child"));
Output result:Name: Zhao Yi's cub, age: 2
Read by instance
At this time, the requirements change again and need to be read at the same timeUser
Andchild
For node data, let’s try the following method to see if it is feasible:
//Register
services.Configure<UserOption>(Configuration.GetSection("User"));
services.Configure<UserOption>(Configuration.GetSection("User:child"));
//Controller
public class HomeController : ControllerBase
{
private readonly UserOption user;
private readonly UserOption child;
public HomeController(IOptions<UserOption> userOptions, IOptions<UserOption> childOptions)
{
user = userOptions.Value;
child = childOptions.Value;
}
[HttpGet]
public string Get()
{
Return $"Name: {user. Username}, age: {user. Userage} \ R \ nname: {child. Username}, age: {child. Userage}";
}
}
Obviously, the output results can not meet our needs:
Name: Zhao Yi's cub, age: 2
Name: Zhao Yi's cub, age: 2
Some small partners will certainly say that a child node field is added to the entity model. This is certainly no problem, but it is no different from the conventional reading method.
What I want to say here is to read by instance and introduceConfigure
Another overloaded method, different from the previous one, has one more parametername
:
public static IServiceCollection Configure<TOptions>(this IServiceCollection services, string name, IConfiguration config) where TOptions : class;
Now let’s re register:
services.Configure<UserOption>("father", Configuration.GetSection("User"));
services.Configure<UserOption>("son", Configuration.GetSection("User:child"));
Injection in the controller constructor also introduces a new interface object:IOptionsMonitor
public class HomeController : ControllerBase
{
private readonly UserOption user;
private readonly UserOption child;
public HomeController(IOptionsMonitor<UserOption> userOptions, IOptionsMonitor<UserOption> childOptions)
{
user = userOptions.Get("father");
child = childOptions.Get("son");
}
[HttpGet]
public string Get()
{
Return $"Name: {user. Username}, age: {user. Userage} \ R \ nname: {child. Username}, age: {child. Userage}";
}
Output result:
Name: Zhao Yi, age: 18
Name: Zhao Yi's cub, age: 2
In fact, there is another interface object that can achieve this effect:IOptionsSnapshot
, thatIOptionsMonitor
AndIOptionsSnapshot
What’s the difference? Please keep looking down.
Differences between ioptionsmonitor and ioptionssnapshot
Let’s take a look at Microsoft’s official comments:
IOptionsMonitor
//
//Summary:
// Used for notifications when TOptions instances change.
//
//Type parameter:
// TOptions:
// The options type.
public interface IOptionsMonitor<out TOptions>
{
//
//Summary:
// Returns the current TOptions instance with the Microsoft.Extensions.Options.Options.DefaultName.
TOptions CurrentValue { get; }
//
//Summary:
// Returns a configured TOptions instance with the given name.
TOptions Get(string name);
//
//Summary:
// Registers a listener to be called whenever a named TOptions changes.
//
//Parameters:
// listener:
// The action to be invoked when TOptions has changed.
//
//Return result:
// An System.IDisposable which should be disposed to stop listening for changes.
IDisposable OnChange(Action<TOptions, string> listener);
}
IOptionsSnapshot
//
//Summary:
// Used to access the value of TOptions for the lifetime of a request.
//
//Type parameter:
// TOptions:
// Options type.
public interface IOptionsSnapshot<out TOptions> : IOptions<TOptions> where TOptions : class, new()
{
//
//Summary:
// Returns a configured TOptions instance with the given name.
TOptions Get(string name);
}
Literally,IOptionsMonitor
It is recommended to be used in the scenario where notification is required after the configuration information is changed, so there are more than oneOnChange
Methods of; andIOptionsSnapshot
It’s a little difficult to understand that it is used to access the configuration within the life cycle of the request. Let’s verify it with code.
Lifecycle of ioptionsmonitor and ioptionsnapshot
Let’s make a small modification to the entity model, add a guid field and give the default value:
public class UserOption
{
public string userName { get; set; }
public int userAge { get; set; }
public Guid guid { get; set; } = Guid.NewGuid();
}
We run the program again:
Father - Name: Zhao Yi, age: 19, No.: e0d71f47-e8f1-4a6d-875e-2074c985f4a0
Son - Name: Zhao Yi's cub, age: 3, number: d865151b-f9bf-4eff-bb4e-8ab6dc61160c
Then keep refreshing the page and you will find that,father
No number has occurred for the number, andson
The number of is changed every time it is refreshed. Is this more like the three modes we use when registering:
services.AddScoped();
services.AddTransient();
services.AddSingleton()
amongfather
similarAddSingleton
,son
Then similarAddScoped
AndAddTransient
。
You can call multiple times in the same methodchildOptions.Get("son")
have a lookson
Similar in the endAddScoped
stillAddTransient
。
Onchange calling mode of ioptionsmonitor
userOptions.OnChange((user,name)=> { Console.WriteLine(user.userName +"-"+ name); });
No file configuration
No file configuration means that it does not need to be configured as a static file. The relevant information does not need to be modified after being configured once. We can use the way of file free configuration, such as those we are familiar withAddCors
Cross domain configuration
services.AddCors(op => {
op.AddPolicy(CorsName, set => {
set.SetIsOriginAllowed(origin => true).AllowAnyHeader().AllowAnyMethod().AllowCredentials();
});
});
We make the following changes to the previous registration method:
services.Configure<UserOption>(c =>
{
c. Username = "Qian Er";
c.userAge = 60;
});
The controller injection adopts the conventional injection method, and the final output result is:Name: Qian Er, age: 60
Share a source code view website:https://source.dot.net/
The above is the whole content of this article. I hope it will be helpful to your study, and I hope you can support developpaer.