Skip to content

Commit

Permalink
add SettingsBuilder.UseEnvironmentVariable()
Browse files Browse the repository at this point in the history
  • Loading branch information
rofr committed Nov 19, 2023
1 parent b7df0d1 commit 6ad30f5
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 31 deletions.
20 changes: 19 additions & 1 deletion Fig.Core/SettingsBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,32 @@ public SettingsBuilder UseDotEnv(string fileName = ".env", string directory = ".
/// <remarks>The path separator (default is _) will be translated to a dot</remarks>
/// </summary>
/// <param name="prefix">For example FIG_, default is no prefix. </param>
/// <param name="dropPrefix">When true, the prefix will not be included in the key</param>
/// <param name="dropPrefix">When true, the prefix will not be included in the key. default is true</param>
/// <returns></returns>
public SettingsBuilder UseEnvironmentVariables(string prefix = "", bool dropPrefix = true)
{
Add(new EnvironmentVariablesSource(prefix, dropPrefix).ToSettingsDictionary());
return this;
}

/// <summary>
/// Read a single environment variable
/// </summary>
/// <param name="name">the name of the environment variable</param>
/// <param name="required"></param>
/// <returns></returns>
/// <exception cref="ConfigurationException">Thrown if the variable is required but not defined</exception>
public SettingsBuilder UseEnvironmentVariable(string name, bool required = false)
{
var val = Environment.GetEnvironmentVariable(name);
if (val is null && required) throw new ConfigurationException("Required ENV var not found: " + name);
if (val != null) Add(new SettingsDictionary()
{
[name] = val
});
return this;
}

private void Add(SettingsDictionary settingsDictionary)
{
_layeredDictionary.Add(settingsDictionary);
Expand Down
30 changes: 30 additions & 0 deletions Fig.Tests/ArrayBindingTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
using NUnit.Framework;

namespace Fig.Test;

public class ArrayBindingTests
{
[Test]
public void CanBindToArray()
{
var settings = new SettingsBuilder()
.UseAppSettingsJson("appsettings.json", required: true)
.Build();

var servers = settings.Get<string[]>("Servers");
Assert.AreEqual(2,servers.Length);
Assert.AreEqual("10.0.0.1", servers[0]);
Assert.AreEqual("10.0.0.2", servers[1]);

var mySettings = settings.Bind<MySettings>(path:"");
Assert.AreEqual(2, mySettings.Servers.Length);
Assert.AreEqual("10.0.0.1", mySettings.Servers[0]);
Assert.AreEqual("10.0.0.2", mySettings.Servers[1]);

}

private class MySettings
{
public string[] Servers { get; set; }
}
}
11 changes: 1 addition & 10 deletions Fig.Tests/appsettings.TEST.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,5 @@
"Simpsons" : [
{ "Name" : "Bart", "Age" : 12},
{ "Name" : "Homer", "Age" : 35}
],

"EnvQualified:PROD" : {
"a" : 1,
"b" : 1
},
"EnvQualified:TEST" : {
"a" : 2,
"b" : 2
}
]
}
11 changes: 1 addition & 10 deletions Fig.Tests/appsettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,5 @@
"Simpsons" : [
{ "Name" : "Bart", "Age" : 12},
{ "Name" : "Homer", "Age" : 35}
],

"EnvQualified:PROD" : {
"a" : 1,
"b" : 1
},
"EnvQualified:TEST" : {
"a" : 2,
"b" : 2
}
]
}
42 changes: 32 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ A .NET Standard 2.0 library to help you read application configuration settings

This README is the documentation.

Breaking changes with version 2.0, please read the [Release notes]() carefully before upgrading from an older version.

## Documentation
Do you have code like the following sprinkled across your code base?

Expand Down Expand Up @@ -99,6 +101,25 @@ DbSettings.ConnectionString
NetworkSettings.TcpPort
NetworkSettings.Retries
```
## Binding to arrays
Append indicies to your configuration keys to define an array:

```
Servers.0 = 10.0.0.1
Servers.1 = 10.0.0.2
```

and then bind to a property of type array:

```csharp
class MySettings
{
public string[] Servers { get; set;}
}
```
Arrays in json files will work this way. See the section below on appsettings.json.

## Variable substitution

## Binding Validation
Properties are either required or optional. To make a property optional, assign it a non-null value before binding.
Expand All @@ -122,6 +143,7 @@ So given the following class:

the `RefillInterval` and `EnableEspressoMachine` parameters are required while the `Greeting` property is optional.


## Retrieving values by key

For simple applications with just a few parameters defining a custom class could be considered over-engineering. In this case you can retrieve values directly by key, either as strings or converted to a desired type.
Expand Down Expand Up @@ -300,7 +322,7 @@ overloads to setup a connection to your database.
```
The SQL query used is `SELECT key, value FROM FigSettings`. You can pass your own query:

```
```csharp
var settings = new SettingsBuilder()
.UseAppSettingsJson("appsettings.json")
.UseSql<SqlConnection>("ConnectionStrings.SQLiteConnection", "SELECT a,b FROM MySettings")
Expand All @@ -314,16 +336,16 @@ lower layers.

```c#
var settings = new SettingsBuilder()
.UseEnvironmentVariable("ENV")
.UseAppSettingsJson("appSettings.json")
.UseAppSettingsJson("appSettings.${ENV}.json", optional:true)
.UseAppSettingsJson("appSettings.${ENV}.json", required:false)
.UseDotEnv()
.UseEnvironmentVariables(prefix: "FIG_", dropPrefix:false)
.UseEnvironmentVariables()
.UseCommandLine(args)
.Build<Settings>();
```
Notice the environment specific json file. The variable `${ENV}`
will be looked up based on what has been added so far:
environment variables and command line.
Notice the variable substitution in the second json file. The variable `${ENV}`
will be looked up in the settings dictionary built so far.

## Install from nuget
```bash
Expand All @@ -347,11 +369,11 @@ with keys and values of each layer:

```
-------------------- Layer 0 ----------------------
| Network.ip:TEST | 127.0.0.1 |
| Network.port:TEST | 13001 |
| Network.ip | 127.0.0.1 |
| Network.port | 13001 |
-------------------- Layer 1 ----------------------
| Network.ip:PROD | 10.0.0.1 |
| Network.port:PROD | 3001 |
| Network.ip | 10.0.0.1 |
| Network.port | 3001 |
---------------------------------------------------
```

Expand Down

0 comments on commit 6ad30f5

Please sign in to comment.