Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ public T Get<T>(string variableName, bool raiseException = false);
public string GetRequired(string variableName);
public object GetRequired(Type type, string variableName);
public T GetRequired<T>(string variableName);

public string GetOrDefault(string variableName, string defaultValue);
public object GetOrDefault(Type type, string variableName, object defaultValue);
public T GetOrDefault<T>(string variableName, T defaultValue);
```

**Example: Basic Usage**
Expand Down Expand Up @@ -63,6 +67,10 @@ public static T Get<T>(string variableName, bool raiseException = false);
public static string GetRequired(string variableName);
public static object GetRequired(Type type, string variableName);
public static T GetRequired<T>(string variableName);

public static string GetOrDefault(string variableName, string defaultValue);
public static object GetOrDefault(Type type, string variableName, object defaultValue);
public static T GetOrDefault<T>(string variableName, T defaultValue);
```

**Example: Static Usage**
Expand Down Expand Up @@ -91,6 +99,10 @@ public static string Get(this Enum key, IEnvManager? envManager = null);
public static object Get(this Enum key, Type type, IEnvManager? envManager = null);
public static T Get<T>(this Enum key, IEnvManager? envManager = null);

public static string GetRequired(this Enum key, IEnvManager? envManager = null);
public static object GetRequired(this Enum key, Type type, IEnvManager? envManager = null);
public static T GetRequired<T>(this Enum key, IEnvManager? envManager = null);

public static string GetRequired(this Enum key, IEnvManager? envManager = null);
public static object GetRequired(this Enum key, Type type, IEnvManager? envManager = null);
public static T GetRequired<T>(this Enum key, IEnvManager? envManager = null);
Expand Down
20 changes: 20 additions & 0 deletions src/EnvironmentManager/Core/EnvManager.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using AutoMapper;
using System.Collections.Generic;
using Microsoft.Extensions.Logging;
using EnvironmentManager.Configuration;
using Microsoft.Extensions.Logging.Abstractions;
Expand Down Expand Up @@ -45,6 +46,25 @@ public T Get<T>(string variableName, bool raiseException = false)
return GetInternal<T>(typeof(T), variableName, raiseException);
}

/// <inheritdoc cref="IEnvManager.GetOrDefault(string, string)"/>
public string GetOrDefault(string variableName, string defaultValue)
{
return GetInternal<string?>(typeof(string), variableName, false) ?? defaultValue;
}

/// <inheritdoc cref="IEnvManager.GetOrDefault(Type, string, object)"/>
public object GetOrDefault(Type type, string variableName, object defaultValue)
{
return GetInternal<object?>(type, variableName, false) ?? defaultValue;
}

/// <inheritdoc cref="IEnvManager.GetOrDefault{T}(string, T)"/>
public T GetOrDefault<T>(string variableName, T defaultValue)
{
var value = GetInternal<T>(typeof(T), variableName, false);
return value == null || EqualityComparer<T>.Default.Equals(value, default!) ? defaultValue : value;
}

/// <inheritdoc cref="IEnvManager.GetRequired(string)"/>
public string GetRequired(string variableName)
{
Expand Down
29 changes: 29 additions & 0 deletions src/EnvironmentManager/Core/IEnvManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,35 @@ public interface IEnvManager
/// <returns>An object of type <typeparamref name="T"/>, or the <see langword="default"/> value of <typeparamref name="T"/> if the variable is not found and <paramref name="raiseException"/> is <see langword="false"/>.</returns>
public T Get<T>(string variableName, bool raiseException = false);

/// <summary>
/// Retrieves the environment variable with the specified <paramref name="variableName"/>;
/// if the variable is missing, empty, or equals its intrinsic <see langword="default"/> value, returns the supplied <paramref name="defaultValue"/> instead.
/// </summary>
/// <param name="variableName">The name of the environment variable to retrieve.</param>
/// <param name="defaultValue">The fallback value to return when the variable is not found or cannot be converted.</param>
/// <returns>The environment-variable value as a <see cref="string"/>, or the provided <paramref name="defaultValue"/> when the variable is not present or invalid.</returns>
public string GetOrDefault(string variableName, string defaultValue);

/// <summary>
/// Retrieves the environment variable with the specified <paramref name="variableName"/> and converts it to the specified <paramref name="type"/>;
/// if the variable is missing or cannot be converted, returns the supplied <paramref name="defaultValue"/>.
/// </summary>
/// <param name="type">The target <see cref="Type"/> to which the environment variable should be converted.</param>
/// <param name="variableName">The name of the environment variable to retrieve.</param>
/// <param name="defaultValue">The fallback value to return when the variable is not found or conversion fails.</param>
/// <returns>An object of the specified <paramref name="type"/>, or the provided <paramref name="defaultValue"/> when the variable is not present or cannot be converted.</returns>
public object GetOrDefault(Type type, string variableName, object defaultValue);

/// <summary>
/// Retrieves the environment variable with the specified <paramref name="variableName"/> and converts it to the specified type <typeparamref name="T"/>;
/// if the variable is missing or cannot be converted, returns the supplied <paramref name="defaultValue"/>.
/// </summary>
/// <typeparam name="T">The target type to which the environment variable should be converted.</typeparam>
/// <param name="variableName">The name of the environment variable to retrieve.</param>
/// <param name="defaultValue">The fallback value to return when the variable is not found or conversion fails.</param>
/// <returns>An object of type <typeparamref name="T"/>, or the provided <paramref name="defaultValue"/> when the variable is not present or cannot be converted.</returns>
public T GetOrDefault<T>(string variableName, T defaultValue);

/// <summary>
/// Retrieves the required environment variable with the specified <paramref name="variableName"/>.<br/>
/// Throws an exception if the environment variable is not found.
Expand Down
53 changes: 53 additions & 0 deletions src/EnvironmentManager/Extensions/EnumExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,59 @@ public static T Get<T>(this Enum key, IEnvManager? envManager = null)
return manager.Get<T>(key.ToString(), attribute?.IsRequired ?? false);
}

/// <summary>
/// Retrieves the environment variable associated with the given enum value and converts it to the <see cref="string"/> type;
/// if the variable is missing or empty, returns the supplied <paramref name="defaultValue"/>.
/// </summary>
/// <param name="key">The enum value representing the environment variable.</param>
/// <param name="defaultValue">The fallback value to return when the variable is not found or its value is <see langword="null"/> / empty.</param>
/// <param name="envManager">The <see cref="IEnvManager"/> to use for retrieving the environment variable. If <see langword="null"/>, the static <see cref="Static.EnvManager.Manager"/> will be used.</param>
/// <returns>The environment-variable value as a <see cref="string"/>, or the provided <paramref name="defaultValue"/> when the variable is not present or invalid.</returns>
/// <remarks>The <see cref="EnvironmentVariableAttribute.IsRequired"/> flag is ignored: the variable is always treated as optional, because a default value is supplied.</remarks>
public static string GetOrDefault(this Enum key, string defaultValue, IEnvManager? envManager = null)
{
var manager = GetEnvManager(envManager);
return manager.GetOrDefault(key.ToString(), defaultValue);
}

/// <summary>
/// Retrieves the environment variable associated with the given enum value and converts it to the specified <paramref name="type"/>;
/// if the variable is missing or cannot be converted, returns the supplied <paramref name="defaultValue"/>.
/// </summary>
/// <param name="key">The enum value representing the environment variable.</param>
/// <param name="type">The target <see cref="Type"/> for conversion.</param>
/// <param name="defaultValue">The fallback value to return when the variable is not found or conversion fails.</param>
/// <param name="envManager">The <see cref="IEnvManager"/> to use for retrieving the environment variable. If <see langword="null"/>, the static <see cref="Static.EnvManager.Manager"/> will be used.</param>
/// <returns>An object of the specified <paramref name="type"/>, or the provided <paramref name="defaultValue"/> when the variable is not present or cannot be converted.</returns>
/// <remarks>
/// The <see cref="EnvironmentVariableAttribute"/> applied to the enum field (if any) is ignored in favour of the explicit <paramref name="type"/> parameter.
/// <see cref="EnvironmentVariableAttribute.IsRequired"/> is ignored because a default value is available.
/// </remarks>
public static object GetOrDefault(this Enum key, Type type, object defaultValue, IEnvManager? envManager = null)
{
var manager = GetEnvManager(envManager);
return manager.GetOrDefault(type, key.ToString(), defaultValue);
}

/// <summary>
/// Retrieves the environment variable associated with the given enum value and converts it to the specified type <typeparamref name="T"/>;
/// if the variable is missing or cannot be converted, returns the supplied <paramref name="defaultValue"/>.
/// </summary>
/// <typeparam name="T">The target type for conversion.</typeparam>
/// <param name="key">The enum value representing the environment variable.</param>
/// <param name="defaultValue">The fallback value to return when the variable is not found or conversion fails.</param>
/// <param name="envManager">The <see cref="IEnvManager"/> to use for retrieving the environment variable. If <see langword="null"/>, the static <see cref="Static.EnvManager.Manager"/> will be used.</param>
/// <returns>An object of type <typeparamref name="T"/>, or the provided <paramref name="defaultValue"/> when the variable is not present or cannot be converted.</returns>
/// <remarks>
/// The <see cref="EnvironmentVariableAttribute"/> applied to the enum field (if any) is ignored in favour of the generic type <typeparamref name="T"/>.
/// <see cref="EnvironmentVariableAttribute.IsRequired"/> is ignored because a default value is supplied.
/// </remarks>
public static T GetOrDefault<T>(this Enum key, T defaultValue, IEnvManager? envManager = null)
{
var manager = GetEnvManager(envManager);
return manager.GetOrDefault<T>(key.ToString(), defaultValue);
}

/// <summary>
/// Retrieves the required environment variable associated with the given enum value, converted to the <see cref="string"/> type.<br/>
/// Throws an exception if the variable is not found.
Expand Down
18 changes: 18 additions & 0 deletions src/EnvironmentManager/Static/EnvManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,24 @@ public static T Get<T>(string variableName, bool raiseException = false)
return Manager.Get<T>(variableName, raiseException);
}

/// <inheritdoc cref="IEnvManager.GetOrDefault(string, string)"/>
public static string GetOrDefault(string variableName, string defaultValue)
{
return Manager.GetOrDefault(variableName, defaultValue);
}

/// <inheritdoc cref="IEnvManager.GetOrDefault(Type, string, object)"/>
public static object GetOrDefault(Type type, string variableName, object defaultValue)
{
return Manager.GetOrDefault(type, variableName, defaultValue);
}

/// <inheritdoc cref="IEnvManager.GetOrDefault{T}(string, T)"/>
public static T GetOrDefault<T>(string variableName, T defaultValue)
{
return Manager.GetOrDefault<T>(variableName, defaultValue);
}

/// <inheritdoc cref="IEnvManager.GetRequired(string)"/>
public static string GetRequired(string variableName)
{
Expand Down
84 changes: 84 additions & 0 deletions test/EnvironmentManager.Tests/Core/EnvManagerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using EnvironmentManager.Configuration;
using EnvironmentManager.Tests.TestHelpers;
using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.VisualStudio.TestPlatform.Utilities;

namespace EnvironmentManager.Tests.Core;

Expand Down Expand Up @@ -85,6 +86,89 @@ public void WhenValidValue_ShouldReturnConvertedValue<TOutput>(string stored, TO
}
}

public class GetOrDefault_String : TestData
{
private readonly string _defaultValue = "Bye World!";

[Fact]
public void WhenValidValue_ShouldReturnConvertedValue()
{
var stored = "Hello World!";
var variableName = NameOfVariable<string>();
Environment.SetEnvironmentVariable(variableName, stored);

var result = EnvironmentManager.GetOrDefault(variableName, _defaultValue);

result.Should().BeEquivalentTo(stored);
}

[Fact]
public void WhenNotFoundValue_ShouldReturnDefaultValue()
{
var variableName = NameOfVariable<string>();

var result = EnvironmentManager.GetOrDefault(variableName, _defaultValue);

result.Should().BeEquivalentTo(_defaultValue);
}
}

public class GetOrDefault_Typed : TestData
{
[Theory]
[MemberData(nameof(CommonTestData))]
[MemberData(nameof(ImplementedTestData))]
public void WhenValidValue_ShouldReturnConvertedValue<TOutput>(string stored, TOutput expected)
{
var variableName = NameOfVariable<TOutput>();
Environment.SetEnvironmentVariable(variableName, stored);

var result = EnvironmentManager.GetOrDefault(typeof(TOutput), variableName, null!);

result.Should().BeEquivalentTo(expected);
}

[Theory]
[MemberData(nameof(CommonTestData))]
[MemberData(nameof(ImplementedTestData))]
public void WhenNotFoundValue_ShouldReturnDefaultValue<TOutput>(string _, TOutput defaultValue)
{
var variableName = NameOfVariable<TOutput>();

var result = EnvironmentManager.GetOrDefault(typeof(TOutput), variableName, defaultValue!);

result.Should().BeEquivalentTo(defaultValue);
}
}

public class GetOrDefault_Generic : TestData
{
[Theory]
[MemberData(nameof(CommonTestData))]
[MemberData(nameof(ImplementedTestData))]
public void WhenValidValue_ShouldReturnConvertedValue<TOutput>(string stored, TOutput expected)
{
var variableName = NameOfVariable<TOutput>();
Environment.SetEnvironmentVariable(variableName, stored);

var result = EnvironmentManager.GetOrDefault<TOutput>(variableName, default!);

result.Should().BeEquivalentTo(expected);
}

[Theory]
[MemberData(nameof(CommonTestData))]
[MemberData(nameof(ImplementedTestData))]
public void WhenNotFoundValue_ShouldReturnDefaultValue<TOutput>(string _, TOutput defaultValue)
{
var variableName = NameOfVariable<TOutput>();

var result = EnvironmentManager.GetOrDefault(variableName, defaultValue!);

result.Should().BeEquivalentTo(defaultValue);
}
}

public class GetRequired_String : TestData
{
[Fact]
Expand Down
80 changes: 80 additions & 0 deletions test/EnvironmentManager.Tests/Extensions/EnumExtensionsTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,86 @@ public void WhenValidValue_ShouldReturnConvertedValue<TOutput>(Enum enumMember,
}
}

public class GetOrDefault_String : TestData
{
private readonly string _defaultValue = "Bye World!";

[Fact]
public void WhenValidValue_ShouldReturnConvertedValue()
{
var stored = "Hello World!";
Environment.SetEnvironmentVariable(TestEnum.STRING.ToString(), stored);

var result = TestEnum.STRING.GetOrDefault(_defaultValue, EnvironmentManager);

result.Should().BeEquivalentTo(stored);
}

[Fact]
public void WhenNotFoundValue_ShouldReturnDefaultValue()
{
Environment.SetEnvironmentVariable(TestEnum.STRING.ToString(), null);

var result = TestEnum.STRING.GetOrDefault(_defaultValue, EnvironmentManager);

result.Should().BeEquivalentTo(_defaultValue);
}
}

public class GetOrDefault_Typed : TestData
{
[Theory]
[MemberData(nameof(EnumTestData))]
[MemberData(nameof(ImplementedEnumTestData))]
public void WhenValidValue_ShouldReturnConvertedValue<TOutput>(Enum enumMember, string stored, TOutput expected)
{
Environment.SetEnvironmentVariable(enumMember.ToString(), stored);

var result = enumMember.GetOrDefault(typeof(TOutput), null!, EnvironmentManager);

result.Should().BeEquivalentTo(expected);
}

[Theory]
[MemberData(nameof(EnumTestData))]
[MemberData(nameof(ImplementedEnumTestData))]
public void WhenNotFoundValue_ShouldReturnDefaultValue<TOutput>(Enum enumMember, string _, TOutput defaultValue)
{
Environment.SetEnvironmentVariable(enumMember.ToString(), null);

var result = enumMember.GetOrDefault(typeof(TOutput), defaultValue!, EnvironmentManager);

result.Should().BeEquivalentTo(defaultValue);
}
}

public class GetOrDefault_Generic : TestData
{
[Theory]
[MemberData(nameof(EnumTestData))]
[MemberData(nameof(ImplementedEnumTestData))]
public void WhenValidValue_ShouldReturnConvertedValue<TOutput>(Enum enumMember, string stored, TOutput expected)
{
Environment.SetEnvironmentVariable(enumMember.ToString(), stored);

var result = enumMember.GetOrDefault<TOutput>(default!, EnvironmentManager);

result.Should().BeEquivalentTo(expected);
}

[Theory]
[MemberData(nameof(EnumTestData))]
[MemberData(nameof(ImplementedEnumTestData))]
public void WhenNotFoundValue_ShouldReturnDefaultValue<TOutput>(Enum enumMember, string _, TOutput defaultValue)
{
Environment.SetEnvironmentVariable(enumMember.ToString(), null);

var result = enumMember.GetOrDefault(typeof(TOutput), defaultValue!, EnvironmentManager);

result.Should().BeEquivalentTo(defaultValue);
}
}

public class GetRequired_String : TestData
{
[Fact]
Expand Down
3 changes: 3 additions & 0 deletions test/EnvironmentManager.Tests/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
using Xunit;

[assembly: CollectionBehavior(DisableTestParallelization = true, MaxParallelThreads = 1)]
Loading