I came from JS so C# is still very confusing to me. But these 2 ways are working as of today (2024-08-12) in .NET 8.0.303:
USING .env
dotnet new console --framework net8.0 --use-program-main
dotnet add package DotNetEnv
your <project_name>.csproj
file should look like this
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>disable</ImplicitUsings> <!-- Enabled by default, I recommend to disable -->
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="DotNetEnv" Version="3.1.0" />
</ItemGroup>
</Project>
now create a .env
file in your project root folder (where Program.cs
is located). this is mine for example:
# ---------------------- Telegram ----------------------
TELEGRAM_BOT_TOKEN='0123456789:Aa1Bb2Cc3...'
# ---------------------- PostgreSQL ----------------------
POSTGRESQL_HOST='localhost'
POSTGRESQL_PORT='5432'
POSTGRESQL_DATABASE='postgres'
POSTGRESQL_USERNAME='postgres'
POSTGRESQL_PASSWORD='1234'
Now, in your Program.cs
you must use DotNetEnv.Env.Load()
(otherwise you will need to use this method inside every namespace that needs environment variables)
using System;
namespace ProjectName;
public static class Program {
internal static void Main() {
DotNetEnv.Env.Load(); // only this in Main method of Program.cs is enough, all namespaces now will have access to the environment variables through the method System.Environment.GetEnvironmentVariable
// ------------------------- encapsulate this within the logic of a certain namespace and class that you want -------------------------
string myEnvironmentVariable = Environment.GetEnvironmentVariable("TELEGRAM_BOT_TOKEN")!; // return type is string? not string
if (String.IsNullOrEmpty(myEnvironmentVariable)) throw new Exception($"{nameof(myEnvironmentVariable)} was not properly initialized.");
// ------------------------- encapsulate this within the logic of a certain namespace and class that you want -------------------------
}
}
USING appsettings.json
dotnet new console --framework net8.0 --use-program-main
dotnet add package Microsoft.Extensions.Configuration
dotnet add package Microsoft.Extensions.Configuration.Json
your <project_name>.csproj
file should look like this
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>disable</ImplicitUsings> <!-- Enabled by default, I recommend to disable -->
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Configuration" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="8.0.0" />
</ItemGroup>
<!--
You must add this otherwise you will receive an error
Unhandled exception. System.IO.FileNotFoundException: The configuration file 'appsettings.json' was not found and is not optional.
The expected physical path was '<project_path>\bin\Debug\net8.0\appsettings.json'.
-->
<ItemGroup>
<None Update="appsettings.json"> <!-- Adding this, will make appsettings.json be copied to <project_path>\bin\Debug\net8.0 -->
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>
now create a appsettings.json
file in your project root folder (where Program.cs
is located). this is mine for example:
{
"Telegram": {
"BotToken": "0123456789:Aa1Bb2Cc3..."
},
"PostgreSQL": {
"Host": "localhost",
"Port": "5432",
"Database": "postgres",
"Username": "postgres",
"Password": "1234"
}
}
Now, in your Program.cs
using System;
using Microsoft.Extensions.Configuration;
namespace ProjectName;
public static class Program {
internal static void Main() {
IConfigurationRoot config = new ConfigurationBuilder()
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: false)
.Build(); // only this in Main method of Program.cs is NOT enough, only this namespace will have access to the enviroment variables
// To resolve this problem, create a Centralized Configuration Class, or something like that
// ------------------------- encapsulate this within the logic of a certain namespace and class that you want -------------------------
string myEnvironmentVariable = config["Telegram:BotToken"]!; // return type is string? not string
if (String.IsNullOrEmpty(myEnvironmentVariable)) throw new Exception($"{nameof(myEnvironmentVariable)} was not properly initialized.");
// ------------------------- encapsulate this within the logic of a certain namespace and class that you want -------------------------
}
}