[C#] Managing External Configuration and Handling OS Differences Using Environment Variables

目次

Overview

This article explains how to retrieve environment variables to manage application configuration information (such as API keys and database connection strings) separately from your source code. By using System.Environment.GetEnvironmentVariable, you can access settings and system paths across different platforms like Windows, Linux, and macOS using a unified code structure.

Specifications (Input/Output)

  • Input: The key name of the environment variable you want to retrieve (string).
  • Target (Optional): Search scope (Process, User, or Machine).
  • Output: The value set in the variable (string). Returns null if the variable does not exist.
  • Behavior:
    • By default, it refers to the environment variables of the current process space.
    • Note the case sensitivity of variable names depending on the OS (Windows is case-insensitive, while Linux and macOS are case-sensitive).

Basic Usage

Retrieve the value by specifying the key name. A common pattern is to combine this with the null-coalescing operator (??) to set a default value if the result is null.

// If "MY_CONFIG" is not set, use "DefaultValue"
string configValue = Environment.GetEnvironmentVariable("MY_CONFIG") ?? "DefaultValue";
Console.WriteLine($"Config: {configValue}");

Full Code

This scenario retrieves an “API key” and the “user’s home directory” when the application starts. It includes logic to handle different environment variable names used by different operating systems (Windows vs. Linux).

using System;

class Program
{
    static void Main()
    {
        Console.WriteLine("=== Loading Application Settings ===");

        // 1. Retrieving configuration values (assuming injection from cloud or Docker environments)
        // Since the return value can be null, set default values as needed.
        string apiKey = Environment.GetEnvironmentVariable("APP_API_KEY");
        string dbHost = Environment.GetEnvironmentVariable("DB_HOST") ?? "localhost";

        // Mask sensitive information for display
        string displayKey = string.IsNullOrEmpty(apiKey) ? "(Not Set)" : "********";

        Console.WriteLine($"API Key : {displayKey}");
        Console.WriteLine($"DB Host : {dbHost}");

        // 2. Cross-platform path retrieval
        // The variable for home directory varies by OS (Windows: USERPROFILE, Unix-like: HOME)
        string homeDir = GetHomeDirectory();

        Console.WriteLine($"Home Dir: {homeDir}");

        // 3. Checking behavior for non-existent variables
        string unknown = Environment.GetEnvironmentVariable("UNDEFINED_VAR");
        if (unknown == null)
        {
            Console.WriteLine("Debug   : The specified environment variable does not exist.");
        }
    }

    // Helper method to retrieve the home directory regardless of OS
    static string GetHomeDirectory()
    {
        // Try the Unix-standard "HOME" first
        string path = Environment.GetEnvironmentVariable("HOME");

        if (string.IsNullOrEmpty(path))
        {
            // If not found, try the Windows-standard "USERPROFILE"
            path = Environment.GetEnvironmentVariable("USERPROFILE");
        }

        return path ?? "Unknown";
    }
}

Execution Result Example (Windows)

=== Loading Application Settings ===
API Key : (Not Set)
DB Host : localhost
Home Dir: C:\Users\DevUser
Debug   : The specified environment variable does not exist.

Customization Points

  • Specifying Variable Scopes: By providing a second argument, such as Environment.GetEnvironmentVariable("Path", EnvironmentVariableTarget.Machine), you can retrieve persistent environment variables for the entire system or a specific user, rather than just the current process.
  • Evaluating as Boolean Values: If using variables as flags (e.g., ENABLE_LOGGING=true), add logic to parse the retrieved string using bool.TryParse.

Points of Caution

  • Case Sensitivity by OS: On Windows, PATH and Path are treated as the same. However, on Linux and macOS, they are distinct variables. When developing cross-platform applications, it is safer to adopt a convention of using uppercase names (e.g., APP_CONFIG).
  • Reflection Lag: Changes to Windows system environment variables are not immediately reflected in processes or terminals that are already running. A restart of the application or the shell is required.
  • Logging Sensitive Information: Environment variables often contain passwords or tokens. Always mask these values or avoid logging them entirely to ensure security.

Application

Dumping All Environment Variables

To check what variables are defined within a container or on a server during debugging, you can list all variables.

using System.Collections;

public static void PrintAllVariables()
{
    // Retrieve all variables in IDictionary format
    IDictionary variables = Environment.GetEnvironmentVariables();

    foreach (DictionaryEntry entry in variables)
    {
        Console.WriteLine($"{entry.Key} = {entry.Value}");
    }
}

Summary

Environment.GetEnvironmentVariable is an essential tool for improving application portability. By avoiding hard-coded values and injecting configurations through environment variables (following patterns like The Twelve-Factor App), you can seamlessly switch between development, testing, and production environments.

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

私が勉強したこと、実践したこと、してることを書いているブログです。
主に資産運用について書いていたのですが、
最近はプログラミングに興味があるので、今はそればっかりです。

目次