Environment and Configuration
Accessing environment variables
.NET provides access to environment variables via the
System.Environment.GetEnvironmentVariable
method. This method retrieves the
value of an environment variable at runtime.
using System;
const string name = "EXAMPLE_VARIABLE";
var value = Environment.GetEnvironmentVariable(name);
if (string.IsNullOrEmpty(value))
Console.WriteLine($"Variable '{name}' not set.");
else
Console.WriteLine($"Variable '{name}' set to '{value}'.");
Rust provides the same environment variable access functionality at
runtime via the var
and var_os
functions from the std::env
module.
The var
function will return a Result<String, VarError>
, and either returns the
variable if it is set or returns an error if the variable is either not set or is not
valid Unicode.
var_os
has a different signature giving back an Option<OsString>
, either
returning some value if the variable is set, or returning None if the variable
is not set. An OsString
is not required to be valid Unicode.
use std::env;
fn main() {
let key = "ExampleVariable";
match env::var(key) {
Ok(val) => println!("{key}: {val:?}"),
Err(e) => println!("couldn't interpret {key}: {e}"),
}
}
use std::env;
fn main() {
let key = "ExampleVariable";
match env::var_os(key) {
Some(val) => println!("{key}: {val:?}"),
None => println!("{key} not defined in the enviroment"),
}
}
Rust also provides environment variable access functionality at
compile time. The env!
macro from std::env
expands the value of the variable
at compile time, returning a &'static str
. If the variable is not set, an
error is emitted.
use std::env;
fn main() {
let example = env!("ExampleVariable");
println!("{example}");
}
In .NET compile time access to environment variables can be achieved, albeit in a less straightforward way, via source generators.
Configuration
Configuration in .NET is possible with configuration providers. The framework
provides several provider implementations via
Microsoft.Extensions.Configuration
namespace and NuGet packages.
Configuration providers read configuration data from key-value pairs using
different sources and provide a unified view of the configuration via the
IConfiguration
type.
using Microsoft.Extensions.Configuration;
class Example {
static void Main()
{
IConfiguration configuration = new ConfigurationBuilder()
.AddEnvironmentVariables()
.Build();
var example = configuration.GetValue<string>("ExampleVar");
Console.WriteLine(example);
}
}
Other provider examples can be found in the official documentation Configurations provider in .NET.
A similar configuration experience in Rust is available via use of third-party crates such as figment or config.
See the following example making use of config crate:
use config::{Config, Environment};
fn main() {
let builder = Config::builder().add_source(Environment::default());
match builder.build() {
Ok(config) => {
match config.get_string("examplevar") {
Ok(v) => println!("{v}"),
Err(e) => println!("{e}")
}
},
Err(_) => {
// something went wrong
}
}
}