Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Creating a IConfigurationBuilder method extension for environment variables #64

Closed
ptsneves opened this issue Nov 14, 2021 · 5 comments
Closed

Comments

@ptsneves
Copy link

Hello,
I think it would be useful to have a IConfigurationBuilder method extension for dev work. Would you be open to accept a pull request for such functionality?

@rogusdev
Copy link
Collaborator

Sure, that sounds great :)

@rogusdev
Copy link
Collaborator

You can create the pr whenever, I will close this issue now

@ptsneves
Copy link
Author

ptsneves commented Dec 3, 2021

Hey @rogusdev
I privately created the extension but it brings Microsoft.Extensions.Configuration as a dependency. Only after I opened the issue did I notice that the dependencies of dotnet-env are very lightweight.

Sorry for wasting your time and thank you for your work on dotnet-env.

If you would be open to add the dependency I will submit the PR.

@rogusdev
Copy link
Collaborator

rogusdev commented Dec 4, 2021

Yeah, I'd rather not have a new dependency for that. Tho, if your extension method is short, you could post it on this thread to help others who have the same desire :)

@ptsneves
Copy link
Author

ptsneves commented Dec 6, 2021

Short if not for all the boiler plate. It was inspired by aspnet code so it needs to comply with the Apache license as in the header:

//
// Licensed under the Apache License, Version 2.0.
// See https://github.com/aspnet/Configuration/blob/master/LICENSE.txt for license information.

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using DotNetEnv;
using Microsoft.Extensions.Configuration;

namespace ProgramExtensions {
    public static class EnvFileExtension {
        public static IConfigurationBuilder LoadEnvironmentVariablesFromFile(this IConfigurationBuilder builder,
            string path, string prefix, LoadOptions options) {
            return builder.Add(new EnvFileConfigurationSource(path, prefix, options));
        }
    }

    public class EnvFileConfigurationSource : IConfigurationSource {
        private readonly LoadOptions _load_options;
        private readonly string _path;
        private readonly string _prefix;

        public EnvFileConfigurationSource(string path, string prefix, LoadOptions load_options) {
            _load_options = load_options;
            _path = path;
            _prefix = prefix;
        }

        public IConfigurationProvider Build(IConfigurationBuilder builder)
        {
            return new EnvFileConfigurationProvider(_path, _prefix, _load_options);
        }
    }

    public class EnvFileConfigurationProvider : ConfigurationProvider{
        private readonly LoadOptions _options;
        private readonly string _path;
        private readonly string _prefix;

        public EnvFileConfigurationProvider(string path, string prefix, LoadOptions options) {
            _options = options;
            _path = path;
            _prefix = prefix;
        }

        public override void Load() {
            var env = Env.Load(_path, _options).ToDictionary();

            var data = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
            var filtered_variables = env
                .SelectMany(NormalizeKey)
                .Where(entry => ((string)entry.Key).StartsWith(_prefix, StringComparison.OrdinalIgnoreCase));

            foreach (var envVariable in filtered_variables)
            {
                var key = ((string)envVariable.Key)[_prefix.Length..];
                data[key] = (string)envVariable.Value;
            }

            Data = data;
        }

        private static IEnumerable<DictionaryEntry> NormalizeKey(KeyValuePair<string, string> e) {
            var (key, value) = e;
            yield return new DictionaryEntry() {
                Key = NormalizeKey(key),
                Value = value
            };
        }

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants