I am developing a web application in ASP.NET Core and currently have a large set of keys, such as stripe account keys. Instead of having them spread throughout the project i
In appsettings.json keep the variables.
{
    "foo": "value1",
    "bar": "value2",
}
Create AppSettings class.
public class AppSettings
{
    public string foo { get; set; }
    public string bar { get; set; }
}
In Startup.cs file register.
public IServiceProvider ConfigureServices(IServiceCollection services)
{
    services.Configure<AppSettings>(Configuration);
}
Usage,
public class MyController : Controller
{
    private readonly IOptions<AppSettings> _appSettings;
    public MyController(IOptions<AppSettings> appSettings)
    {
        _appSettings = appSettings;
    }
    var fooValue = _appSettings.Value.foo;
    var barValue = _appSettings.Value.bar;
}
I often do this kind of thing with connection strings and other global constants.  First create a class for those variables that you need.  In my project it is MDUOptions but whatever you want.
public class MDUOptions
{
    public string mduConnectionString { get; set; }
    public string secondaryConnectionString { get; set; }
}
Now in your Startup.cs ConfigureServices method:
Action<MDU.MDUOptions> mduOptions = (opt =>
{
    opt.mduConnectionString = Configuration["ConnectionStrings:mduConnection"];
});
services.Configure(mduOptions);
services.AddSingleton(resolver => resolver.GetRequiredService<IOptions<MDUOptions>>().Value);
Now you use DI to access it in code:
public class PropertySalesRepository : IPropertySalesRepository
{
    private static string _mduDb;
    public PropertySalesRepository(MDUOptions options)
    {
        _mduDb = options.mduConnectionString;
    }
    ....
}
In my case the only property I wanted was the string but I could have used the entire options class.