Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# - Require an environment variable in ConfigurationBuilder

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.

like image 225
GettingPleasure Avatar asked Sep 13 '25 03:09

GettingPleasure


2 Answers

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.

like image 97
Guru Stron Avatar answered Sep 14 '25 17:09

Guru Stron


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.

like image 27
thewallrus Avatar answered Sep 14 '25 19:09

thewallrus