问题
I am building a console application in .NET Core 2.2.
I added strongly-typed configuration like this:
var configuration = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", true)
.AddCommandLine(args)
.Build();
services.Configure<AppConfiguration>(configuration);
My configuration is bound to an object of class AppConfiguration
. I wonder, how can I catch exceptions that could happen while binding config values to my class? For example, one of my configuration properties is an enum. If user provides nonexisting parameter, I get exception with stack trace:
at System.Enum.TryParseEnum(Type enumType, String value, Boolean ignoreCase, EnumResult& parseResult) at System.Enum.Parse(Type enumType, String value, Boolean ignoreCase) at System.ComponentModel.EnumConverter.ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, Object value)
Basically, I need some way to know that exception happened because of wrong configuration and not some other problem. If I was able to catch any configuration binding-related exceptions, I could throw my own WrongConfigurationException to catch it and be sure that something was wrong with config.
回答1:
Fail early by eagerly getting/binding the desired object from configuration and catching any exceptions thrown during startup.
Reference Bind to an object graph
//...
var configuration = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", true)
.AddCommandLine(args)
.Build();
try {
//bind to object graph
AppConfiguration appConfig = configuration.Get<AppConfiguration>();
//custom validation can be done here as well
//...
//if valid add to service collection.
services.AddSingleton(appConfig);
} catch(Exception ex) {
throw new WrongConfigurationException("my message here", ex);
}
//...
Note that with the above example the class can be explicitly injected into dependents without having to be wrapped in IOptions<T>, which has its own design implications
The try-catch can also be foregone by just letting it fail at that point.
//...
var configuration = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", true)
.AddCommandLine(args)
.Build();
//bind to object graph
AppConfiguration appConfig = configuration.Get<AppConfiguration>();
//custom validation can be done here as well
if(/*conditional appConfig*/)
throw new WrongConfigurationException("my message here");
//if valid add to service collection.
services.AddSingleton(appConfig);
//...
It should easily indicate where and why the exception was thrown.
来源:https://stackoverflow.com/questions/56974195/how-to-catch-configuration-binding-exception