I want to require an environment variable to be set before running my ASP.NET Core server. I use ConfigurationBuilder
to bind variables to a structure that lives in my object.
Here's a sample:
public class Config
{
[ConfigurationKeyName("NOT_REQUIRED_VARIABLE")]
public string? First { get; set; } = "first";
[ConfigurationKeyName("REQUIRED_VARIABLE")]
public string? Second { get; set; }
public Config()
{
new ConfigurationBuilder()
.AddEnvironmentVariables()
.Build()
.Bind(this);
}
}
In this sample, after calling new Config()
without setting any environment variable, we will get an object that has "first"
set in First
field (not required to be set in environment) and a null string in Second
.
Is there a way to set a variable to be required or not required specifically? It's gonna be a huge pain checking every non-required variable by hand in config creation or in business logic.
There is nothing out of the box as far as I know. You can utilize System.ComponentModel.DataAnnotations
with it's attributes and Validator
. For example RequiredAtrribute
will check if property is set to not-null value:
public class Config
{
[ConfigurationKeyName("NOT_REQUIRED_VARIABLE")]
public string? First { get; set; } = "first";
[ConfigurationKeyName("REQUIRED_VARIABLE")]
[Required]
public string? Second { get; set; }
public Config()
{
new ConfigurationBuilder()
.AddEnvironmentVariables()
.Build()
.Bind(this);
Validator.ValidateObject(this, new ValidationContext(this));
}
}
Note that it has some quirks like handling value types (Required
will result in check against default
value for example).
Or you can use popular FluentValidation
but basically with the same effect:
public class Config
{
[ConfigurationKeyName("NOT_REQUIRED_VARIABLE")]
public string? First { get; set; } = "first";
[ConfigurationKeyName("REQUIRED_VARIABLE")]
public string? Second { get; set; }
public Config()
{
new ConfigurationBuilder()
.AddEnvironmentVariables()
.Build()
.Bind(this);
new Validator().ValidateAndThrow(this);
}
public class Validator : AbstractValidator<Config>
{
public Validator()
{
RuleFor(x => x.Second).NotEmpty();
}
}
}
Note that both of them will not actually check if environment variable was provided but only the bound value.
Using DataAnnotations
and [Required]
attribute is a way to set a variable as required/not required.
From your comments - If you are required to implement your own Config class using ConfiguraitonBuilder
, you would also implement your own validation. To validate your config properties in the posted code you could manually check for null of each property, use reflection, use a source generator, or there is a built in Validator
class (which also uses reflection):
public class Config
{
[ConfigurationKeyName("NOT_REQUIRED_VARIABLE")]
public string? First { get; set; } = "first";
[Required]
[ConfigurationKeyName("REQUIRED_VARIABLE")]
public string? Second { get; set; }
public Config()
{
new ConfigurationBuilder()
.AddEnvironmentVariables()
.Build()
.Bind(this);
Validator.ValidateObject(this, new ValidationContext(this), true);
}
}
If you're not required to implement your own config class, I would suggest to do what Martin Costello is saying in the comments, which would probably make you use Dependency Injection and options pattern instead of having new Config()
in your code.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With