Skip to content

Commit

Permalink
Remove LINQ usage from EnvironmentVariablesConfigurationProvider (#44923
Browse files Browse the repository at this point in the history
)
  • Loading branch information
stephentoub authored Nov 20, 2020
1 parent f2e83d7 commit 8d38285
Showing 1 changed file with 47 additions and 66 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;

namespace Microsoft.Extensions.Configuration.EnvironmentVariables
{
Expand All @@ -18,101 +17,83 @@ public class EnvironmentVariablesConfigurationProvider : ConfigurationProvider
private const string SqlServerPrefix = "SQLCONNSTR_";
private const string CustomPrefix = "CUSTOMCONNSTR_";

private const string ConnStrKeyFormat = "ConnectionStrings:{0}";
private const string ProviderKeyFormat = "ConnectionStrings:{0}_ProviderName";

private readonly string _prefix;

/// <summary>
/// Initializes a new instance.
/// </summary>
public EnvironmentVariablesConfigurationProvider() : this(string.Empty)
{ }
public EnvironmentVariablesConfigurationProvider() =>
_prefix = string.Empty;

/// <summary>
/// Initializes a new instance with the specified prefix.
/// </summary>
/// <param name="prefix">A prefix used to filter the environment variables.</param>
public EnvironmentVariablesConfigurationProvider(string prefix)
{
public EnvironmentVariablesConfigurationProvider(string prefix) =>
_prefix = prefix ?? string.Empty;
}

/// <summary>
/// Loads the environment variables.
/// </summary>
public override void Load()
{
public override void Load() =>
Load(Environment.GetEnvironmentVariables());
}

internal void Load(IDictionary envVariables)
{
var data = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);

IEnumerable<DictionaryEntry> filteredEnvVariables = envVariables
.Cast<DictionaryEntry>()
.SelectMany(AzureEnvToAppEnv)
.Where(entry => ((string)entry.Key).StartsWith(_prefix, StringComparison.OrdinalIgnoreCase));

foreach (DictionaryEntry envVariable in filteredEnvVariables)
foreach (DictionaryEntry entry in envVariables)
{
string key = ((string)envVariable.Key).Substring(_prefix.Length);
data[key] = (string)envVariable.Value;
string key = (string)entry.Key;
string provider = null;
string prefix;

if (key.StartsWith(MySqlServerPrefix, StringComparison.OrdinalIgnoreCase))
{
prefix = MySqlServerPrefix;
provider = "MySql.Data.MySqlClient";
}
else if (key.StartsWith(SqlAzureServerPrefix, StringComparison.OrdinalIgnoreCase))
{
prefix = SqlAzureServerPrefix;
provider = "System.Data.SqlClient";
}
else if (key.StartsWith(SqlServerPrefix, StringComparison.OrdinalIgnoreCase))
{
prefix = SqlServerPrefix;
provider = "System.Data.SqlClient";
}
else if (key.StartsWith(CustomPrefix, StringComparison.OrdinalIgnoreCase))
{
prefix = CustomPrefix;
}
else
{
AddIfPrefixed(data, NormalizeKey(key), (string)entry.Value);
continue;
}

// Add the key-value pair for connection string, and optionally provider name
key = NormalizeKey(key.Substring(prefix.Length));
AddIfPrefixed(data, $"ConnectionStrings:{key}", (string)entry.Value);
if (provider != null)
{
AddIfPrefixed(data, $"ConnectionStrings:{key}_ProviderName", provider);
}
}

Data = data;
}

private static string NormalizeKey(string key)
private void AddIfPrefixed(Dictionary<string, string> data, string key, string value)
{
return key.Replace("__", ConfigurationPath.KeyDelimiter);
}

private static IEnumerable<DictionaryEntry> AzureEnvToAppEnv(DictionaryEntry entry)
{
string key = (string)entry.Key;
string prefix = string.Empty;
string provider = string.Empty;

if (key.StartsWith(MySqlServerPrefix, StringComparison.OrdinalIgnoreCase))
{
prefix = MySqlServerPrefix;
provider = "MySql.Data.MySqlClient";
}
else if (key.StartsWith(SqlAzureServerPrefix, StringComparison.OrdinalIgnoreCase))
if (key.StartsWith(_prefix, StringComparison.OrdinalIgnoreCase))
{
prefix = SqlAzureServerPrefix;
provider = "System.Data.SqlClient";
}
else if (key.StartsWith(SqlServerPrefix, StringComparison.OrdinalIgnoreCase))
{
prefix = SqlServerPrefix;
provider = "System.Data.SqlClient";
}
else if (key.StartsWith(CustomPrefix, StringComparison.OrdinalIgnoreCase))
{
prefix = CustomPrefix;
}
else
{
entry.Key = NormalizeKey(key);
yield return entry;
yield break;
}

// Return the key-value pair for connection string
yield return new DictionaryEntry(
string.Format(ConnStrKeyFormat, NormalizeKey(key.Substring(prefix.Length))),
entry.Value);

if (!string.IsNullOrEmpty(provider))
{
// Return the key-value pair for provider name
yield return new DictionaryEntry(
string.Format(ProviderKeyFormat, NormalizeKey(key.Substring(prefix.Length))),
provider);
key = key.Substring(_prefix.Length);
data[key] = value;
}
}

private static string NormalizeKey(string key) => key.Replace("__", ConfigurationPath.KeyDelimiter);
}
}

0 comments on commit 8d38285

Please sign in to comment.