├── .appveyor.yml
├── .gitattributes
├── .gitignore
├── .travis.yml
├── .vsts-pipelines
└── builds
│ ├── ci-internal.yml
│ └── ci-public.yml
├── CONTRIBUTING.md
├── Configuration.sln
├── Directory.Build.props
├── Directory.Build.targets
├── LICENSE.txt
├── NuGet.config
├── NuGetPackageVerifier.json
├── README.md
├── build.cmd
├── build.sh
├── build
├── Key.snk
├── dependencies.props
├── repo.props
└── sources.props
├── korebuild-lock.txt
├── korebuild.json
├── run.cmd
├── run.ps1
├── run.sh
├── samples
└── KeyVaultSample
│ ├── EnvironmentSecretManager.cs
│ ├── KeyVaultSample.csproj
│ ├── Program.cs
│ └── settings.json
├── src
├── Config.Abstractions
│ ├── Config.Abstractions.csproj
│ ├── ConfigurationExtensions.cs
│ ├── ConfigurationPath.cs
│ ├── IConfiguration.cs
│ ├── IConfigurationBuilder.cs
│ ├── IConfigurationProvider.cs
│ ├── IConfigurationRoot.cs
│ ├── IConfigurationSection.cs
│ ├── IConfigurationSource.cs
│ └── baseline.netcore.json
├── Config.AzureKeyVault
│ ├── AzureKeyVaultConfigurationExtensions.cs
│ ├── AzureKeyVaultConfigurationProvider.cs
│ ├── AzureKeyVaultConfigurationSource.cs
│ ├── Config.AzureKeyVault.csproj
│ ├── DefaultKeyVaultSecretManager.cs
│ ├── IKeyVaultClient.cs
│ ├── IKeyVaultSecretManager.cs
│ ├── KeyVaultClientWrapper.cs
│ ├── Properties
│ │ └── AssemblyInfo.cs
│ └── baseline.netcore.json
├── Config.Binder
│ ├── BinderOptions.cs
│ ├── Config.Binder.csproj
│ ├── ConfigurationBinder.cs
│ ├── Properties
│ │ ├── AssemblyInfo.cs
│ │ └── Resources.Designer.cs
│ ├── Resources.resx
│ └── baseline.netcore.json
├── Config.CommandLine
│ ├── CommandLineConfigurationExtensions.cs
│ ├── CommandLineConfigurationProvider.cs
│ ├── CommandLineConfigurationSource.cs
│ ├── Config.CommandLine.csproj
│ ├── Properties
│ │ ├── AssemblyInfo.cs
│ │ └── Resources.Designer.cs
│ ├── Resources.resx
│ └── baseline.netcore.json
├── Config.EnvironmentVariables
│ ├── Config.EnvironmentVariables.csproj
│ ├── EnvironmentVariablesConfigurationProvider.cs
│ ├── EnvironmentVariablesConfigurationSource.cs
│ ├── EnvironmentVariablesExtensions.cs
│ ├── Properties
│ │ └── AssemblyInfo.cs
│ └── baseline.netcore.json
├── Config.FileExtensions
│ ├── Config.FileExtensions.csproj
│ ├── FileConfigurationExtensions.cs
│ ├── FileConfigurationProvider.cs
│ ├── FileConfigurationSource.cs
│ ├── FileLoadExceptionContext.cs
│ ├── Properties
│ │ ├── AssemblyInfo.cs
│ │ └── Resources.Designer.cs
│ ├── Resources.resx
│ └── baseline.netcore.json
├── Config.Ini
│ ├── Config.Ini.csproj
│ ├── IniConfigurationExtensions.cs
│ ├── IniConfigurationProvider.cs
│ ├── IniConfigurationSource.cs
│ ├── Properties
│ │ ├── AssemblyInfo.cs
│ │ └── Resources.Designer.cs
│ ├── Resources.resx
│ └── baseline.netcore.json
├── Config.Json
│ ├── Config.Json.csproj
│ ├── JsonConfigurationExtensions.cs
│ ├── JsonConfigurationFileParser.cs
│ ├── JsonConfigurationProvider.cs
│ ├── JsonConfigurationSource.cs
│ ├── Properties
│ │ ├── AssemblyInfo.cs
│ │ └── Resources.Designer.cs
│ ├── Resources.resx
│ └── baseline.netcore.json
├── Config.KeyPerFile
│ ├── Config.KeyPerFile.csproj
│ ├── KeyPerFileConfigurationBuilderExtensions.cs
│ ├── KeyPerFileConfigurationProvider.cs
│ ├── KeyPerFileConfigurationSource.cs
│ └── README.md
├── Config.UserSecrets
│ ├── Config.UserSecrets.csproj
│ ├── PathHelper.cs
│ ├── Properties
│ │ ├── AssemblyInfo.cs
│ │ └── Resources.Designer.cs
│ ├── Resources.resx
│ ├── UserSecretsConfigurationExtensions.cs
│ ├── UserSecretsIdAttribute.cs
│ ├── baseline.netcore.json
│ └── build
│ │ └── netstandard2.0
│ │ ├── Microsoft.Extensions.Configuration.UserSecrets.props
│ │ └── Microsoft.Extensions.Configuration.UserSecrets.targets
├── Config.Xml
│ ├── Config.Xml.csproj
│ ├── Properties
│ │ ├── AssemblyInfo.cs
│ │ └── Resources.Designer.cs
│ ├── Resources.resx
│ ├── XmlConfigurationExtensions.cs
│ ├── XmlConfigurationProvider.cs
│ ├── XmlConfigurationSource.cs
│ ├── XmlDocumentDecryptor.cs
│ └── baseline.netcore.json
├── Config
│ ├── ChainedBuilderExtensions.cs
│ ├── ChainedConfigurationProvider.cs
│ ├── ChainedConfigurationSource.cs
│ ├── Config.csproj
│ ├── ConfigurationBuilder.cs
│ ├── ConfigurationKeyComparer.cs
│ ├── ConfigurationProvider.cs
│ ├── ConfigurationReloadToken.cs
│ ├── ConfigurationRoot.cs
│ ├── ConfigurationSection.cs
│ ├── MemoryConfigurationBuilderExtensions.cs
│ ├── MemoryConfigurationProvider.cs
│ ├── MemoryConfigurationSource.cs
│ ├── Properties
│ │ ├── AssemblyInfo.cs
│ │ └── Resources.Designer.cs
│ ├── Resources.resx
│ └── baseline.netcore.json
└── Directory.Build.props
├── test
├── Config.AzureKeyVault.Test
│ ├── AzureKeyVaultConfigurationTest.cs
│ └── Config.AzureKeyVault.Test.csproj
├── Config.Binder.Test
│ ├── Config.Binder.Test.csproj
│ ├── ConfigurationBinderTests.cs
│ └── ConfigurationCollectionBindingTests.cs
├── Config.CommandLine.Test
│ ├── CommandLineTest.cs
│ └── Config.CommandLine.Test.csproj
├── Config.EnvironmentVariables.Test
│ ├── Config.EnvironmentVariables.Test.csproj
│ └── EnvironmentVariablesTest.cs
├── Config.FileExtensions.Test
│ ├── Config.FileExtensions.Test.csproj
│ └── FileConfigurationBuilderExtensionsTest.cs
├── Config.FunctionalTests
│ ├── ArrayTests.cs
│ ├── Config.FunctionalTests.csproj
│ ├── ConfigurationTests.cs
│ ├── DisposableFileSystem.cs
│ └── test.xml
├── Config.Ini.Test
│ ├── Config.Ini.Test.csproj
│ ├── IniConfigurationExtensionsTest.cs
│ └── IniConfigurationTest.cs
├── Config.Json.Test
│ ├── ArrayTest.cs
│ ├── Config.Json.Test.csproj
│ ├── JsonConfigurationExtensionsTest.cs
│ └── JsonConfigurationTest.cs
├── Config.KeyPerFile.Test
│ ├── Config.KeyPerFile.Test.csproj
│ └── KeyPerFileTests.cs
├── Config.Test.Common
│ ├── Config.Test.Common.csproj
│ ├── ConfigurationProviderExtensions.cs
│ └── TestStreamHelpers.cs
├── Config.Test
│ ├── Config.Test.csproj
│ ├── ConfigurationPathComparerTest.cs
│ ├── ConfigurationPathTest.cs
│ └── ConfigurationTest.cs
├── Config.UserSecrets.Test
│ ├── Config.UserSecrets.Test.csproj
│ ├── ConfigurationExtensionTest.cs
│ ├── MsBuildTargetTest.cs
│ └── PathHelperTest.cs
├── Config.Xml.Test
│ ├── Config.Xml.Test.csproj
│ ├── XmlConfigurationExtensionsTest.cs
│ └── XmlConfigurationTest.cs
└── Directory.Build.props
└── version.props
/.appveyor.yml:
--------------------------------------------------------------------------------
1 | init:
2 | - git config --global core.autocrlf true
3 | branches:
4 | only:
5 | - master
6 | - /^release\/.*$/
7 | - /^(.*\/)?ci-.*$/
8 | build_script:
9 | - ps: .\run.ps1 default-build
10 | clone_depth: 1
11 | environment:
12 | global:
13 | DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true
14 | DOTNET_CLI_TELEMETRY_OPTOUT: 1
15 | test: 'off'
16 | deploy: 'off'
17 | os: Visual Studio 2017
18 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | *.doc diff=astextplain
2 | *.DOC diff=astextplain
3 | *.docx diff=astextplain
4 | *.DOCX diff=astextplain
5 | *.dot diff=astextplain
6 | *.DOT diff=astextplain
7 | *.pdf diff=astextplain
8 | *.PDF diff=astextplain
9 | *.rtf diff=astextplain
10 | *.RTF diff=astextplain
11 |
12 | *.jpg binary
13 | *.png binary
14 | *.gif binary
15 |
16 | *.cs text=auto diff=csharp
17 | *.vb text=auto
18 | *.resx text=auto
19 | *.c text=auto
20 | *.cpp text=auto
21 | *.cxx text=auto
22 | *.h text=auto
23 | *.hxx text=auto
24 | *.py text=auto
25 | *.rb text=auto
26 | *.java text=auto
27 | *.html text=auto
28 | *.htm text=auto
29 | *.css text=auto
30 | *.scss text=auto
31 | *.sass text=auto
32 | *.less text=auto
33 | *.js text=auto
34 | *.lisp text=auto
35 | *.clj text=auto
36 | *.sql text=auto
37 | *.php text=auto
38 | *.lua text=auto
39 | *.m text=auto
40 | *.asm text=auto
41 | *.erl text=auto
42 | *.fs text=auto
43 | *.fsx text=auto
44 | *.hs text=auto
45 |
46 | *.csproj text=auto
47 | *.vbproj text=auto
48 | *.fsproj text=auto
49 | *.dbproj text=auto
50 | *.sln text=auto eol=crlf
51 | *.sh eol=lf
52 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | [Oo]bj/
2 | [Bb]in/
3 | TestResults/
4 | .nuget/
5 | _ReSharper.*/
6 | packages/
7 | artifacts/
8 | PublishProfiles/
9 | *.user
10 | *.suo
11 | *.cache
12 | *.docstates
13 | _ReSharper.*
14 | nuget.exe
15 | *net45.csproj
16 | *net451.csproj
17 | *k10.csproj
18 | *.psess
19 | *.vsp
20 | *.pidb
21 | *.userprefs
22 | *DS_Store
23 | *.ncrunchsolution
24 | *.*sdf
25 | *.ipch
26 | *.sln.ide
27 | project.lock.json
28 | .vs
29 | .vscode/
30 | .build/
31 | .testPublish/
32 | *.nuget.props
33 | *.nuget.targets
34 | global.json
35 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: csharp
2 | sudo: false
3 | dist: trusty
4 | env:
5 | global:
6 | - DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true
7 | - DOTNET_CLI_TELEMETRY_OPTOUT: 1
8 | mono: none
9 | os:
10 | - linux
11 | - osx
12 | osx_image: xcode8.2
13 | addons:
14 | apt:
15 | packages:
16 | - libunwind8
17 | branches:
18 | only:
19 | - master
20 | - /^release\/.*$/
21 | - /^(.*\/)?ci-.*$/
22 | before_install:
23 | - if test "$TRAVIS_OS_NAME" == "osx"; then brew update; brew install openssl; ln -s
24 | /usr/local/opt/openssl/lib/libcrypto.1.0.0.dylib /usr/local/lib/; ln -s /usr/local/opt/openssl/lib/libssl.1.0.0.dylib
25 | /usr/local/lib/; fi
26 | script:
27 | - ./build.sh
28 |
--------------------------------------------------------------------------------
/.vsts-pipelines/builds/ci-internal.yml:
--------------------------------------------------------------------------------
1 | trigger:
2 | - master
3 | - release/*
4 |
5 | resources:
6 | repositories:
7 | - repository: buildtools
8 | type: git
9 | name: aspnet-BuildTools
10 | ref: refs/heads/master
11 |
12 | phases:
13 | - template: .vsts-pipelines/templates/project-ci.yml@buildtools
14 |
--------------------------------------------------------------------------------
/.vsts-pipelines/builds/ci-public.yml:
--------------------------------------------------------------------------------
1 | trigger:
2 | - master
3 | - release/*
4 |
5 | # See https://github.com/aspnet/BuildTools
6 | resources:
7 | repositories:
8 | - repository: buildtools
9 | type: github
10 | endpoint: DotNet-Bot GitHub Connection
11 | name: aspnet/BuildTools
12 | ref: refs/heads/master
13 |
14 | phases:
15 | - template: .vsts-pipelines/templates/project-ci.yml@buildtools
16 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | Contributing
2 | ======
3 |
4 | Information on contributing to this repo is in the [Contributing Guide](https://github.com/aspnet/Home/blob/master/CONTRIBUTING.md) in the Home repo.
5 |
--------------------------------------------------------------------------------
/Directory.Build.props:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
8 |
9 |
10 |
11 | Microsoft .NET Extensions
12 | https://github.com/aspnet/Configuration
13 | git
14 | $(MSBuildThisFileDirectory)
15 | $(MSBuildThisFileDirectory)build\Key.snk
16 | true
17 | true
18 |
19 |
20 |
--------------------------------------------------------------------------------
/Directory.Build.targets:
--------------------------------------------------------------------------------
1 |
2 |
3 | $(MicrosoftNETCoreApp20PackageVersion)
4 | $(MicrosoftNETCoreApp21PackageVersion)
5 | $(MicrosoftNETCoreApp22PackageVersion)
6 | $(NETStandardLibrary20PackageVersion)
7 |
8 | 99.9
9 |
10 |
11 |
--------------------------------------------------------------------------------
/NuGet.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/NuGetPackageVerifier.json:
--------------------------------------------------------------------------------
1 | {
2 | "Default": {
3 | "rules": [
4 | "DefaultCompositeRule"
5 | ]
6 | }
7 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Configuration [Archived]
2 | ========================
3 |
4 | **This GitHub project has been archived.** Ongoing development on this project can be found in .
5 |
6 | Configuration is a framework for accessing Key/Value based configuration settings in an application. Includes configuration providers for command line arguments, environment variables, INI files, JSON files, and XML files.
7 |
8 | This project is part of ASP.NET Core. You can find samples, documentation and getting started instructions for ASP.NET Core at the [AspNetCore](https://github.com/aspnet/AspNetCore) repo.
9 |
--------------------------------------------------------------------------------
/build.cmd:
--------------------------------------------------------------------------------
1 | @ECHO OFF
2 | PowerShell -NoProfile -NoLogo -ExecutionPolicy unrestricted -Command "[System.Threading.Thread]::CurrentThread.CurrentCulture = ''; [System.Threading.Thread]::CurrentThread.CurrentUICulture = '';& '%~dp0run.ps1' default-build %*; exit $LASTEXITCODE"
3 |
--------------------------------------------------------------------------------
/build.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | set -euo pipefail
4 | DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
5 |
6 | # Call "sync" between "chmod" and execution to prevent "text file busy" error in Docker (aufs)
7 | chmod +x "$DIR/run.sh"; sync
8 | "$DIR/run.sh" default-build "$@"
9 |
--------------------------------------------------------------------------------
/build/Key.snk:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aspnet/Configuration/f64994e0655659faefccead7ccb5c1edbfd4d4ba/build/Key.snk
--------------------------------------------------------------------------------
/build/dependencies.props:
--------------------------------------------------------------------------------
1 |
2 |
3 | $(MSBuildAllProjects);$(MSBuildThisFileFullPath)
4 |
5 |
6 | 3.0.0-alpha1-20181004.7
7 | 3.0.0-alpha1-10584
8 | 2.3.2
9 | 1.0.1
10 | 3.0.0-alpha1-10584
11 | 3.0.0-alpha1-10584
12 | 2.0.9
13 | 2.1.3
14 | 2.2.0-preview2-26905-02
15 | 15.6.1
16 | 4.9.0
17 | 2.0.3
18 | 11.0.2
19 | 4.6.0-preview1-26907-04
20 | 2.3.1
21 | 2.4.0
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/build/repo.props:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 | Internal.AspNetCore.Universe.Lineup
11 | https://dotnet.myget.org/F/aspnetcore-dev/api/v3/index.json
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/build/sources.props:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | $(DotNetRestoreSources)
6 |
7 | $(RestoreSources);
8 | https://dotnet.myget.org/F/dotnet-core/api/v3/index.json;
9 | https://dotnet.myget.org/F/aspnetcore-dev/api/v3/index.json;
10 | https://dotnet.myget.org/F/aspnetcore-tools/api/v3/index.json;
11 |
12 |
13 | $(RestoreSources);
14 | https://api.nuget.org/v3/index.json;
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/korebuild-lock.txt:
--------------------------------------------------------------------------------
1 | version:3.0.0-alpha1-20181004.7
2 | commithash:27fabdaf2b1d4753c3d2749581694ca65d78f7f2
3 |
--------------------------------------------------------------------------------
/korebuild.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://raw.githubusercontent.com/aspnet/BuildTools/master/tools/korebuild.schema.json",
3 | "channel": "master"
4 | }
5 |
--------------------------------------------------------------------------------
/run.cmd:
--------------------------------------------------------------------------------
1 | @ECHO OFF
2 | PowerShell -NoProfile -NoLogo -ExecutionPolicy unrestricted -Command "[System.Threading.Thread]::CurrentThread.CurrentCulture = ''; [System.Threading.Thread]::CurrentThread.CurrentUICulture = '';& '%~dp0run.ps1' %*; exit $LASTEXITCODE"
3 |
--------------------------------------------------------------------------------
/samples/KeyVaultSample/EnvironmentSecretManager.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.Azure.KeyVault.Models;
2 | using Microsoft.Extensions.Configuration.AzureKeyVault;
3 |
4 | namespace ConsoleApplication
5 | {
6 | public class EnvironmentSecretManager : DefaultKeyVaultSecretManager
7 | {
8 | private readonly string _environmentPrefix;
9 |
10 | public EnvironmentSecretManager(string environment)
11 | {
12 | _environmentPrefix = environment + "-";
13 | }
14 |
15 | public override bool Load(SecretItem secret)
16 | {
17 | return HasEnvironmentPrefix(secret.Identifier.Name);
18 | }
19 |
20 | public override string GetKey(SecretBundle secret)
21 | {
22 | var keyName = base.GetKey(secret);
23 |
24 | return HasEnvironmentPrefix(keyName)
25 | ? keyName.Substring(_environmentPrefix.Length)
26 | : keyName;
27 | }
28 |
29 | private bool HasEnvironmentPrefix(string name)
30 | {
31 | return name.StartsWith(_environmentPrefix);
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/samples/KeyVaultSample/KeyVaultSample.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netcoreapp2.2;net461
5 | portable
6 | Exe
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/samples/KeyVaultSample/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Security.Cryptography.X509Certificates;
5 | using Microsoft.Extensions.Configuration;
6 |
7 | namespace ConsoleApplication
8 | {
9 | public class Program
10 | {
11 | public static void Main(string[] args)
12 | {
13 | var builder = new ConfigurationBuilder();
14 | builder.AddJsonFile("settings.json");
15 |
16 | var config = builder.Build();
17 |
18 | var store = new X509Store(StoreLocation.CurrentUser);
19 | store.Open(OpenFlags.ReadOnly);
20 | var cert = store.Certificates.Find(X509FindType.FindByThumbprint, config["CertificateThumbprint"], false);
21 |
22 | builder.AddAzureKeyVault(
23 | config["Vault"],
24 | config["ClientId"],
25 | cert.OfType().Single(),
26 | new EnvironmentSecretManager("Development"));
27 | store.Close();
28 |
29 | config = builder.Build();
30 |
31 | Console.WriteLine(config["ConnectionString"]);
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/samples/KeyVaultSample/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "CertificateThumbprint": "",
3 | "Vault": "",
4 | "ClientId": ""
5 | }
6 |
--------------------------------------------------------------------------------
/src/Config.Abstractions/Config.Abstractions.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Microsoft.Extensions.Configuration.Abstractions
5 | Microsoft.Extensions.Configuration.Abstractions
6 | Abstractions of key-value pair based configuration.
7 | Commonly used types:
8 | Microsoft.Extensions.Configuration.IConfiguration
9 | Microsoft.Extensions.Configuration.IConfigurationBuilder
10 | Microsoft.Extensions.Configuration.IConfigurationProvider
11 | Microsoft.Extensions.Configuration.IConfigurationRoot
12 | Microsoft.Extensions.Configuration.IConfigurationSection
13 | netstandard2.0
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/src/Config.Abstractions/ConfigurationExtensions.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) .NET Foundation. All rights reserved.
2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3 |
4 | using System;
5 | using System.Collections.Generic;
6 | using System.Linq;
7 |
8 | namespace Microsoft.Extensions.Configuration
9 | {
10 | ///
11 | /// Extension methods for configuration classes./>.
12 | ///
13 | public static class ConfigurationExtensions
14 | {
15 | ///
16 | /// Adds a new configuration source.
17 | ///
18 | /// The to add to.
19 | /// Configures the source secrets.
20 | /// The .
21 | public static IConfigurationBuilder Add(this IConfigurationBuilder builder, Action configureSource) where TSource : IConfigurationSource, new()
22 | {
23 | var source = new TSource();
24 | configureSource?.Invoke(source);
25 | return builder.Add(source);
26 | }
27 |
28 | ///
29 | /// Shorthand for GetSection("ConnectionStrings")[name].
30 | ///
31 | /// The configuration.
32 | /// The connection string key.
33 | ///
34 | public static string GetConnectionString(this IConfiguration configuration, string name)
35 | {
36 | return configuration?.GetSection("ConnectionStrings")?[name];
37 | }
38 |
39 | ///
40 | /// Get the enumeration of key value pairs within the
41 | ///
42 | /// The to enumerate.
43 | /// An enumeration of key value pairs.
44 | public static IEnumerable> AsEnumerable(this IConfiguration configuration) => configuration.AsEnumerable(makePathsRelative: false);
45 |
46 | ///
47 | /// Get the enumeration of key value pairs within the
48 | ///
49 | /// The to enumerate.
50 | /// If true, the child keys returned will have the current configuration's Path trimmed from the front.
51 | /// An enumeration of key value pairs.
52 | public static IEnumerable> AsEnumerable(this IConfiguration configuration, bool makePathsRelative)
53 | {
54 | var stack = new Stack();
55 | stack.Push(configuration);
56 | var rootSection = configuration as IConfigurationSection;
57 | var prefixLength = (makePathsRelative && rootSection != null) ? rootSection.Path.Length + 1 : 0;
58 | while (stack.Count > 0)
59 | {
60 | var config = stack.Pop();
61 | // Don't include the sections value if we are removing paths, since it will be an empty key
62 | if (config is IConfigurationSection section && (!makePathsRelative || config != configuration))
63 | {
64 | yield return new KeyValuePair(section.Path.Substring(prefixLength), section.Value);
65 | }
66 | foreach (var child in config.GetChildren())
67 | {
68 | stack.Push(child);
69 | }
70 | }
71 | }
72 |
73 | ///
74 | /// Determines whether the section has a or has children
75 | ///
76 | public static bool Exists(this IConfigurationSection section)
77 | {
78 | if (section == null)
79 | {
80 | return false;
81 | }
82 | return section.Value != null || section.GetChildren().Any();
83 | }
84 | }
85 | }
--------------------------------------------------------------------------------
/src/Config.Abstractions/ConfigurationPath.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) .NET Foundation. All rights reserved.
2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3 |
4 | using System;
5 | using System.Collections.Generic;
6 |
7 | namespace Microsoft.Extensions.Configuration
8 | {
9 | ///
10 | /// Utility methods and constants for manipulating Configuration paths
11 | ///
12 | public static class ConfigurationPath
13 | {
14 | ///
15 | /// The delimiter ":" used to separate individual keys in a path.
16 | ///
17 | public static readonly string KeyDelimiter = ":";
18 |
19 | ///
20 | /// Combines path segments into one path.
21 | ///
22 | /// The path segments to combine.
23 | /// The combined path.
24 | public static string Combine(params string[] pathSegments)
25 | {
26 | if (pathSegments == null)
27 | {
28 | throw new ArgumentNullException(nameof(pathSegments));
29 | }
30 | return string.Join(KeyDelimiter, pathSegments);
31 | }
32 |
33 | ///
34 | /// Combines path segments into one path.
35 | ///
36 | /// The path segments to combine.
37 | /// The combined path.
38 | public static string Combine(IEnumerable pathSegments)
39 | {
40 | if (pathSegments == null)
41 | {
42 | throw new ArgumentNullException(nameof(pathSegments));
43 | }
44 | return string.Join(KeyDelimiter, pathSegments);
45 | }
46 |
47 | ///
48 | /// Extracts the last path segment from the path.
49 | ///
50 | /// The path.
51 | /// The last path segment of the path.
52 | public static string GetSectionKey(string path)
53 | {
54 | if (string.IsNullOrEmpty(path))
55 | {
56 | return path;
57 | }
58 |
59 | var lastDelimiterIndex = path.LastIndexOf(KeyDelimiter, StringComparison.OrdinalIgnoreCase);
60 | return lastDelimiterIndex == -1 ? path : path.Substring(lastDelimiterIndex + 1);
61 | }
62 |
63 | ///
64 | /// Extracts the path corresponding to the parent node for a given path.
65 | ///
66 | /// The path.
67 | /// The original path minus the last individual segment found in it. Null if the original path corresponds to a top level node.
68 | public static string GetParentPath(string path)
69 | {
70 | if (string.IsNullOrEmpty(path))
71 | {
72 | return null;
73 | }
74 |
75 | var lastDelimiterIndex = path.LastIndexOf(KeyDelimiter, StringComparison.OrdinalIgnoreCase);
76 | return lastDelimiterIndex == -1 ? null : path.Substring(0, lastDelimiterIndex);
77 | }
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/src/Config.Abstractions/IConfiguration.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) .NET Foundation. All rights reserved.
2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3 |
4 | using System.Collections.Generic;
5 | using Microsoft.Extensions.Primitives;
6 |
7 | namespace Microsoft.Extensions.Configuration
8 | {
9 | ///
10 | /// Represents a set of key/value application configuration properties.
11 | ///
12 | public interface IConfiguration
13 | {
14 | ///
15 | /// Gets or sets a configuration value.
16 | ///
17 | /// The configuration key.
18 | /// The configuration value.
19 | string this[string key] { get; set; }
20 |
21 | ///
22 | /// Gets a configuration sub-section with the specified key.
23 | ///
24 | /// The key of the configuration section.
25 | /// The .
26 | ///
27 | /// This method will never return null. If no matching sub-section is found with the specified key,
28 | /// an empty will be returned.
29 | ///
30 | IConfigurationSection GetSection(string key);
31 |
32 | ///
33 | /// Gets the immediate descendant configuration sub-sections.
34 | ///
35 | /// The configuration sub-sections.
36 | IEnumerable GetChildren();
37 |
38 | ///
39 | /// Returns a that can be used to observe when this configuration is reloaded.
40 | ///
41 | /// A .
42 | IChangeToken GetReloadToken();
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/Config.Abstractions/IConfigurationBuilder.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) .NET Foundation. All rights reserved.
2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3 |
4 | using System.Collections.Generic;
5 |
6 | namespace Microsoft.Extensions.Configuration
7 | {
8 | ///
9 | /// Represents a type used to build application configuration.
10 | ///
11 | public interface IConfigurationBuilder
12 | {
13 | ///
14 | /// Gets a key/value collection that can be used to share data between the
15 | /// and the registered s.
16 | ///
17 | IDictionary Properties { get; }
18 |
19 | ///
20 | /// Gets the sources used to obtain configuration values
21 | ///
22 | IList Sources { get; }
23 |
24 | ///
25 | /// Adds a new configuration source.
26 | ///
27 | /// The configuration source to add.
28 | /// The same .
29 | IConfigurationBuilder Add(IConfigurationSource source);
30 |
31 | ///
32 | /// Builds an with keys and values from the set of sources registered in
33 | /// .
34 | ///
35 | /// An with keys and values from the registered sources.
36 | IConfigurationRoot Build();
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/Config.Abstractions/IConfigurationProvider.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) .NET Foundation. All rights reserved.
2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3 |
4 | using System.Collections.Generic;
5 | using Microsoft.Extensions.Primitives;
6 |
7 | namespace Microsoft.Extensions.Configuration
8 | {
9 | ///
10 | /// Provides configuration key/values for an application.
11 | ///
12 | public interface IConfigurationProvider
13 | {
14 | ///
15 | /// Tries to get a configuration value for the specified key.
16 | ///
17 | /// The key.
18 | /// The value.
19 | /// True if a value for the specified key was found, otherwise false.
20 | bool TryGet(string key, out string value);
21 |
22 | ///
23 | /// Sets a configuration value for the specified key.
24 | ///
25 | /// The key.
26 | /// The value.
27 | void Set(string key, string value);
28 |
29 | ///
30 | /// Returns a change token if this provider supports change tracking, null otherwise.
31 | ///
32 | ///
33 | IChangeToken GetReloadToken();
34 |
35 | ///
36 | /// Loads configuration values from the source represented by this .
37 | ///
38 | void Load();
39 |
40 | ///
41 | /// Returns the immediate descendant configuration keys for a given parent path based on this
42 | /// 's data and the set of keys returned by all the preceding
43 | /// s.
44 | ///
45 | /// The child keys returned by the preceding providers for the same parent path.
46 | /// The parent path.
47 | /// The child keys.
48 | IEnumerable GetChildKeys(IEnumerable earlierKeys, string parentPath);
49 | }
50 | }
--------------------------------------------------------------------------------
/src/Config.Abstractions/IConfigurationRoot.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) .NET Foundation. All rights reserved.
2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3 |
4 | using System;
5 | using System.Collections.Generic;
6 |
7 | namespace Microsoft.Extensions.Configuration
8 | {
9 | ///
10 | /// Represents the root of an hierarchy.
11 | ///
12 | public interface IConfigurationRoot : IConfiguration
13 | {
14 | ///
15 | /// Force the configuration values to be reloaded from the underlying s.
16 | ///
17 | void Reload();
18 |
19 | ///
20 | /// The s for this configuration.
21 | ///
22 | IEnumerable Providers { get; }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/Config.Abstractions/IConfigurationSection.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) .NET Foundation. All rights reserved.
2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3 |
4 | namespace Microsoft.Extensions.Configuration
5 | {
6 | ///
7 | /// Represents a section of application configuration values.
8 | ///
9 | public interface IConfigurationSection : IConfiguration
10 | {
11 | ///
12 | /// Gets the key this section occupies in its parent.
13 | ///
14 | string Key { get; }
15 |
16 | ///
17 | /// Gets the full path to this section within the .
18 | ///
19 | string Path { get; }
20 |
21 | ///
22 | /// Gets or sets the section value.
23 | ///
24 | string Value { get; set; }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/Config.Abstractions/IConfigurationSource.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) .NET Foundation. All rights reserved.
2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3 |
4 | using System.Collections.Generic;
5 |
6 | namespace Microsoft.Extensions.Configuration
7 | {
8 | ///
9 | /// Represents a source of configuration key/values for an application.
10 | ///
11 | public interface IConfigurationSource
12 | {
13 | ///
14 | /// Builds the for this source.
15 | ///
16 | /// The .
17 | /// An
18 | IConfigurationProvider Build(IConfigurationBuilder builder);
19 | }
20 | }
--------------------------------------------------------------------------------
/src/Config.AzureKeyVault/AzureKeyVaultConfigurationProvider.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) .NET Foundation. All rights reserved.
2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3 |
4 | using System;
5 | using System.Collections.Generic;
6 | using System.Threading.Tasks;
7 | using Microsoft.Azure.KeyVault;
8 |
9 | namespace Microsoft.Extensions.Configuration.AzureKeyVault
10 | {
11 | ///
12 | /// An AzureKeyVault based .
13 | ///
14 | internal class AzureKeyVaultConfigurationProvider : ConfigurationProvider
15 | {
16 | private readonly IKeyVaultClient _client;
17 | private readonly string _vault;
18 | private readonly IKeyVaultSecretManager _manager;
19 |
20 | ///
21 | /// Creates a new instance of .
22 | ///
23 | /// The to use for retrieving values.
24 | /// Azure KeyVault uri.
25 | ///
26 | public AzureKeyVaultConfigurationProvider(IKeyVaultClient client, string vault, IKeyVaultSecretManager manager)
27 | {
28 | if (client == null)
29 | {
30 | throw new ArgumentNullException(nameof(client));
31 | }
32 | if (vault == null)
33 | {
34 | throw new ArgumentNullException(nameof(vault));
35 | }
36 | if (manager == null)
37 | {
38 | throw new ArgumentNullException(nameof(manager));
39 | }
40 |
41 | _client = client;
42 | _vault = vault;
43 | _manager = manager;
44 | }
45 |
46 | public override void Load() => LoadAsync().ConfigureAwait(false).GetAwaiter().GetResult();
47 |
48 | private async Task LoadAsync()
49 | {
50 | var data = new Dictionary(StringComparer.OrdinalIgnoreCase);
51 |
52 | var secrets = await _client.GetSecretsAsync(_vault).ConfigureAwait(false);
53 | do
54 | {
55 | foreach (var secretItem in secrets)
56 | {
57 | if (!_manager.Load(secretItem) || (secretItem.Attributes?.Enabled != true))
58 | {
59 | continue;
60 | }
61 |
62 | var value = await _client.GetSecretAsync(secretItem.Id).ConfigureAwait(false);
63 | var key = _manager.GetKey(value);
64 | data.Add(key, value.Value);
65 | }
66 |
67 | secrets = secrets.NextPageLink != null ?
68 | await _client.GetSecretsNextAsync(secrets.NextPageLink).ConfigureAwait(false) :
69 | null;
70 | } while (secrets != null);
71 |
72 | Data = data;
73 | }
74 | }
75 | }
--------------------------------------------------------------------------------
/src/Config.AzureKeyVault/AzureKeyVaultConfigurationSource.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) .NET Foundation. All rights reserved.
2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3 |
4 | using Microsoft.Azure.KeyVault;
5 |
6 | namespace Microsoft.Extensions.Configuration.AzureKeyVault
7 | {
8 | ///
9 | /// Represents Azure KeyVault secrets as an .
10 | ///
11 | internal class AzureKeyVaultConfigurationSource : IConfigurationSource
12 | {
13 | ///
14 | /// Gets or sets the to use for retrieving values.
15 | ///
16 | public KeyVaultClient Client { get; set; }
17 |
18 | ///
19 | /// Gets or sets the vault uri.
20 | ///
21 | public string Vault { get; set; }
22 |
23 | ///
24 | /// Gets or sets the instance used to control secret loading.
25 | ///
26 | public IKeyVaultSecretManager Manager { get; set; }
27 |
28 | ///
29 | public IConfigurationProvider Build(IConfigurationBuilder builder)
30 | {
31 | return new AzureKeyVaultConfigurationProvider(new KeyVaultClientWrapper(Client), Vault, Manager);
32 | }
33 | }
34 | }
--------------------------------------------------------------------------------
/src/Config.AzureKeyVault/Config.AzureKeyVault.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Microsoft.Extensions.Configuration.AzureKeyVault
5 | Microsoft.Extensions.Configuration.AzureKeyVault
6 | Azure KeyVault configuration provider implementation for Microsoft.Extensions.Configuration.
7 | netstandard2.0
8 | $(PackageTags);azure;keyvault
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/src/Config.AzureKeyVault/DefaultKeyVaultSecretManager.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) .NET Foundation. All rights reserved.
2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3 |
4 | using Microsoft.Azure.KeyVault;
5 | using Microsoft.Azure.KeyVault.Models;
6 |
7 | namespace Microsoft.Extensions.Configuration.AzureKeyVault
8 | {
9 | ///
10 | /// Default implementation of that loads all secrets
11 | /// and replaces '--' with ':" in key names.
12 | ///
13 | public class DefaultKeyVaultSecretManager : IKeyVaultSecretManager
14 | {
15 | ///
16 | public virtual string GetKey(SecretBundle secret)
17 | {
18 | return secret.SecretIdentifier.Name.Replace("--", ConfigurationPath.KeyDelimiter);
19 | }
20 |
21 | ///
22 | public virtual bool Load(SecretItem secret)
23 | {
24 | return true;
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/Config.AzureKeyVault/IKeyVaultClient.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) .NET Foundation. All rights reserved.
2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3 |
4 | using System.Threading.Tasks;
5 | using Microsoft.Azure.KeyVault;
6 | using Microsoft.Azure.KeyVault.Models;
7 | using Microsoft.Rest.Azure;
8 |
9 | namespace Microsoft.Extensions.Configuration.AzureKeyVault
10 | {
11 | ///
12 | /// Client class to perform cryptographic key operations and vault operations
13 | /// against the Key Vault service.
14 | /// Thread safety: This class is thread-safe.
15 | ///
16 | internal interface IKeyVaultClient
17 | {
18 | /// List secrets in the specified vault
19 | /// The URL for the vault containing the secrets.
20 | /// A response message containing a list of secrets in the vault along with a link to the next page of secrets
21 | Task> GetSecretsAsync(string vault);
22 |
23 | /// Gets a secret.
24 | /// The URL for the secret.
25 | /// A response message containing the secret
26 | Task GetSecretAsync(string secretIdentifier);
27 |
28 | /// List the next page of secrets
29 | /// nextLink value from a previous call to GetSecrets or GetSecretsNext
30 | /// A response message containing a list of secrets in the vault along with a link to the next page of secrets
31 | Task> GetSecretsNextAsync(string nextLink);
32 | }
33 | }
--------------------------------------------------------------------------------
/src/Config.AzureKeyVault/IKeyVaultSecretManager.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) .NET Foundation. All rights reserved.
2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3 |
4 | using Microsoft.Azure.KeyVault.Models;
5 |
6 | namespace Microsoft.Extensions.Configuration.AzureKeyVault
7 | {
8 | ///
9 | /// The instance used to control secret loading.
10 | ///
11 | public interface IKeyVaultSecretManager
12 | {
13 | ///
14 | /// Checks if value should be retrieved.
15 | ///
16 | /// The instance.
17 | /// true
is secrets value should be loaded, otherwise false
.
18 | bool Load(SecretItem secret);
19 |
20 | ///
21 | /// Maps secret to a configuration key.
22 | ///
23 | /// The instance.
24 | /// Configuration key name to store secret value.
25 | string GetKey(SecretBundle secret);
26 | }
27 | }
--------------------------------------------------------------------------------
/src/Config.AzureKeyVault/KeyVaultClientWrapper.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) .NET Foundation. All rights reserved.
2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3 |
4 | using System.Threading.Tasks;
5 | using Microsoft.Azure.KeyVault;
6 | using Microsoft.Azure.KeyVault.Models;
7 | using Microsoft.Rest.Azure;
8 |
9 | namespace Microsoft.Extensions.Configuration.AzureKeyVault
10 | {
11 | ///
12 | internal class KeyVaultClientWrapper : IKeyVaultClient
13 | {
14 | private readonly KeyVaultClient _keyVaultClientImplementation;
15 |
16 | ///
17 | /// Creates a new instance of .
18 | ///
19 | /// The instance to wrap.
20 | public KeyVaultClientWrapper(KeyVaultClient keyVaultClientImplementation)
21 | {
22 | _keyVaultClientImplementation = keyVaultClientImplementation;
23 | }
24 |
25 | ///
26 | public Task> GetSecretsAsync(string vault)
27 | {
28 | return _keyVaultClientImplementation.GetSecretsAsync(vault);
29 | }
30 |
31 | ///
32 | public Task GetSecretAsync(string secretIdentifier)
33 | {
34 | return _keyVaultClientImplementation.GetSecretAsync(secretIdentifier);
35 | }
36 |
37 | ///
38 | public Task> GetSecretsNextAsync(string nextLink)
39 | {
40 | return _keyVaultClientImplementation.GetSecretsNextAsync(nextLink);
41 | }
42 | }
43 | }
--------------------------------------------------------------------------------
/src/Config.AzureKeyVault/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) .NET Foundation. All rights reserved.
2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3 |
4 | using System.Runtime.CompilerServices;
5 |
6 | [assembly: InternalsVisibleTo("Microsoft.Extensions.Configuration.AzureKeyVault.Test, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
7 | [assembly: InternalsVisibleTo("DynamicProxyGenAssembly2, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7")]
8 |
9 |
--------------------------------------------------------------------------------
/src/Config.Binder/BinderOptions.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) .NET Foundation. All rights reserved.
2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3 |
4 | namespace Microsoft.Extensions.Configuration
5 | {
6 | ///
7 | /// Options class used by the .
8 | ///
9 | public class BinderOptions
10 | {
11 | ///
12 | /// When false (the default), the binder will only attempt to set public properties.
13 | /// If true, the binder will attempt to set all non read-only properties.
14 | ///
15 | public bool BindNonPublicProperties { get; set; }
16 | }
17 | }
--------------------------------------------------------------------------------
/src/Config.Binder/Config.Binder.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Microsoft.Extensions.Configuration.Binder
5 | Microsoft.Extensions.Configuration.Binder
6 | Functionality to bind an object to data in configuration providers for Microsoft.Extensions.Configuration.
7 | netstandard2.0
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/src/Config.Binder/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) .NET Foundation. All rights reserved.
2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3 |
4 | using System.Runtime.CompilerServices;
5 |
6 | [assembly: InternalsVisibleTo("Microsoft.Extensions.Configuration.Binder.Test, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
7 |
8 |
--------------------------------------------------------------------------------
/src/Config.Binder/Properties/Resources.Designer.cs:
--------------------------------------------------------------------------------
1 | //
2 | namespace Microsoft.Extensions.Configuration.Binder
3 | {
4 | using System.Globalization;
5 | using System.Reflection;
6 | using System.Resources;
7 |
8 | internal static class Resources
9 | {
10 | private static readonly ResourceManager _resourceManager
11 | = new ResourceManager("Microsoft.Extensions.Configuration.Binder.Resources", typeof(Resources).GetTypeInfo().Assembly);
12 |
13 | ///
14 | /// Cannot create instance of type '{0}' because it is either abstract or an interface.
15 | ///
16 | internal static string Error_CannotActivateAbstractOrInterface
17 | {
18 | get => GetString("Error_CannotActivateAbstractOrInterface");
19 | }
20 |
21 | ///
22 | /// Cannot create instance of type '{0}' because it is either abstract or an interface.
23 | ///
24 | internal static string FormatError_CannotActivateAbstractOrInterface(object p0)
25 | => string.Format(CultureInfo.CurrentCulture, GetString("Error_CannotActivateAbstractOrInterface"), p0);
26 |
27 | ///
28 | /// Failed to convert '{0}' to type '{1}'.
29 | ///
30 | internal static string Error_FailedBinding
31 | {
32 | get => GetString("Error_FailedBinding");
33 | }
34 |
35 | ///
36 | /// Failed to convert '{0}' to type '{1}'.
37 | ///
38 | internal static string FormatError_FailedBinding(object p0, object p1)
39 | => string.Format(CultureInfo.CurrentCulture, GetString("Error_FailedBinding"), p0, p1);
40 |
41 | ///
42 | /// Failed to create instance of type '{0}'.
43 | ///
44 | internal static string Error_FailedToActivate
45 | {
46 | get => GetString("Error_FailedToActivate");
47 | }
48 |
49 | ///
50 | /// Failed to create instance of type '{0}'.
51 | ///
52 | internal static string FormatError_FailedToActivate(object p0)
53 | => string.Format(CultureInfo.CurrentCulture, GetString("Error_FailedToActivate"), p0);
54 |
55 | ///
56 | /// Cannot create instance of type '{0}' because it is missing a public parameterless constructor.
57 | ///
58 | internal static string Error_MissingParameterlessConstructor
59 | {
60 | get => GetString("Error_MissingParameterlessConstructor");
61 | }
62 |
63 | ///
64 | /// Cannot create instance of type '{0}' because it is missing a public parameterless constructor.
65 | ///
66 | internal static string FormatError_MissingParameterlessConstructor(object p0)
67 | => string.Format(CultureInfo.CurrentCulture, GetString("Error_MissingParameterlessConstructor"), p0);
68 |
69 | ///
70 | /// Cannot create instance of type '{0}' because multidimensional arrays are not supported.
71 | ///
72 | internal static string Error_UnsupportedMultidimensionalArray
73 | {
74 | get => GetString("Error_UnsupportedMultidimensionalArray");
75 | }
76 |
77 | ///
78 | /// Cannot create instance of type '{0}' because multidimensional arrays are not supported.
79 | ///
80 | internal static string FormatError_UnsupportedMultidimensionalArray(object p0)
81 | => string.Format(CultureInfo.CurrentCulture, GetString("Error_UnsupportedMultidimensionalArray"), p0);
82 |
83 | private static string GetString(string name, params string[] formatterNames)
84 | {
85 | var value = _resourceManager.GetString(name);
86 |
87 | System.Diagnostics.Debug.Assert(value != null);
88 |
89 | if (formatterNames != null)
90 | {
91 | for (var i = 0; i < formatterNames.Length; i++)
92 | {
93 | value = value.Replace("{" + formatterNames[i] + "}", "{" + i + "}");
94 | }
95 | }
96 |
97 | return value;
98 | }
99 | }
100 | }
101 |
--------------------------------------------------------------------------------
/src/Config.CommandLine/CommandLineConfigurationExtensions.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) .NET Foundation. All rights reserved.
2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3 |
4 | using System;
5 | using System.Collections.Generic;
6 | using Microsoft.Extensions.Configuration.CommandLine;
7 |
8 | namespace Microsoft.Extensions.Configuration
9 | {
10 | ///
11 | /// Extension methods for registering with .
12 | ///
13 | public static class CommandLineConfigurationExtensions
14 | {
15 | ///
16 | /// Adds an that reads configuration values from the command line.
17 | ///
18 | /// The to add to.
19 | /// The command line args.
20 | /// The .
21 | public static IConfigurationBuilder AddCommandLine(this IConfigurationBuilder configurationBuilder, string[] args)
22 | {
23 | return configurationBuilder.AddCommandLine(args, switchMappings: null);
24 | }
25 |
26 | ///
27 | /// Adds an that reads configuration values from the command line using the specified switch mappings.
28 | ///
29 | /// The to add to.
30 | /// The command line args.
31 | /// The switch mappings.
32 | /// The .
33 | public static IConfigurationBuilder AddCommandLine(
34 | this IConfigurationBuilder configurationBuilder,
35 | string[] args,
36 | IDictionary switchMappings)
37 | {
38 | configurationBuilder.Add(new CommandLineConfigurationSource { Args = args, SwitchMappings = switchMappings });
39 | return configurationBuilder;
40 | }
41 |
42 | ///
43 | /// Adds an that reads configuration values from the command line.
44 | ///
45 | /// The to add to.
46 | /// Configures the source.
47 | /// The .
48 | public static IConfigurationBuilder AddCommandLine(this IConfigurationBuilder builder, Action configureSource)
49 | => builder.Add(configureSource);
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/src/Config.CommandLine/CommandLineConfigurationSource.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) .NET Foundation. All rights reserved.
2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3 |
4 | using System.Collections.Generic;
5 |
6 | namespace Microsoft.Extensions.Configuration.CommandLine
7 | {
8 | ///
9 | /// Represents command line arguments as an .
10 | ///
11 | public class CommandLineConfigurationSource : IConfigurationSource
12 | {
13 | ///
14 | /// Gets or sets the switch mappings.
15 | ///
16 | public IDictionary SwitchMappings { get; set; }
17 |
18 | ///
19 | /// Gets or sets the command line args.
20 | ///
21 | public IEnumerable Args { get; set; }
22 |
23 | ///
24 | /// Builds the for this source.
25 | ///
26 | /// The .
27 | /// A
28 | public IConfigurationProvider Build(IConfigurationBuilder builder)
29 | {
30 | return new CommandLineConfigurationProvider(Args, SwitchMappings);
31 | }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/Config.CommandLine/Config.CommandLine.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Microsoft.Extensions.Configuration.CommandLine
5 | Microsoft.Extensions.Configuration.CommandLine
6 | Command line configuration provider implementation for Microsoft.Extensions.Configuration.
7 | netstandard2.0
8 | $(PackageTags);commandline
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/src/Config.CommandLine/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) .NET Foundation. All rights reserved.
2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3 |
4 | using System.Runtime.CompilerServices;
5 |
6 | [assembly: InternalsVisibleTo("Microsoft.Extensions.Configuration.CommandLine.Test, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
7 |
8 |
--------------------------------------------------------------------------------
/src/Config.CommandLine/Properties/Resources.Designer.cs:
--------------------------------------------------------------------------------
1 | //
2 | namespace Microsoft.Extensions.Configuration.CommandLine
3 | {
4 | using System.Globalization;
5 | using System.Reflection;
6 | using System.Resources;
7 |
8 | internal static class Resources
9 | {
10 | private static readonly ResourceManager _resourceManager
11 | = new ResourceManager("Microsoft.Extensions.Configuration.CommandLine.Resources", typeof(Resources).GetTypeInfo().Assembly);
12 |
13 | ///
14 | /// Keys in switch mappings are case-insensitive. A duplicated key '{0}' was found.
15 | ///
16 | internal static string Error_DuplicatedKeyInSwitchMappings
17 | {
18 | get => GetString("Error_DuplicatedKeyInSwitchMappings");
19 | }
20 |
21 | ///
22 | /// Keys in switch mappings are case-insensitive. A duplicated key '{0}' was found.
23 | ///
24 | internal static string FormatError_DuplicatedKeyInSwitchMappings(object p0)
25 | => string.Format(CultureInfo.CurrentCulture, GetString("Error_DuplicatedKeyInSwitchMappings"), p0);
26 |
27 | ///
28 | /// The switch mappings contain an invalid switch '{0}'.
29 | ///
30 | internal static string Error_InvalidSwitchMapping
31 | {
32 | get => GetString("Error_InvalidSwitchMapping");
33 | }
34 |
35 | ///
36 | /// The switch mappings contain an invalid switch '{0}'.
37 | ///
38 | internal static string FormatError_InvalidSwitchMapping(object p0)
39 | => string.Format(CultureInfo.CurrentCulture, GetString("Error_InvalidSwitchMapping"), p0);
40 |
41 | ///
42 | /// The short switch '{0}' is not defined in the switch mappings.
43 | ///
44 | internal static string Error_ShortSwitchNotDefined
45 | {
46 | get => GetString("Error_ShortSwitchNotDefined");
47 | }
48 |
49 | ///
50 | /// The short switch '{0}' is not defined in the switch mappings.
51 | ///
52 | internal static string FormatError_ShortSwitchNotDefined(object p0)
53 | => string.Format(CultureInfo.CurrentCulture, GetString("Error_ShortSwitchNotDefined"), p0);
54 |
55 | private static string GetString(string name, params string[] formatterNames)
56 | {
57 | var value = _resourceManager.GetString(name);
58 |
59 | System.Diagnostics.Debug.Assert(value != null);
60 |
61 | if (formatterNames != null)
62 | {
63 | for (var i = 0; i < formatterNames.Length; i++)
64 | {
65 | value = value.Replace("{" + formatterNames[i] + "}", "{" + i + "}");
66 | }
67 | }
68 |
69 | return value;
70 | }
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/src/Config.EnvironmentVariables/Config.EnvironmentVariables.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Microsoft.Extensions.Configuration.EnvironmentVariables
5 | Microsoft.Extensions.Configuration.EnvironmentVariables
6 | Environment variables configuration provider implementation for Microsoft.Extensions.Configuration.
7 | netstandard2.0
8 | $(PackageTags);envvar;environmentvariable
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/src/Config.EnvironmentVariables/EnvironmentVariablesConfigurationProvider.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) .NET Foundation. All rights reserved.
2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3 |
4 | using System;
5 | using System.Collections;
6 | using System.Collections.Generic;
7 | using System.Linq;
8 |
9 | namespace Microsoft.Extensions.Configuration.EnvironmentVariables
10 | {
11 | ///
12 | /// An environment variable based .
13 | ///
14 | public class EnvironmentVariablesConfigurationProvider : ConfigurationProvider
15 | {
16 | private const string MySqlServerPrefix = "MYSQLCONNSTR_";
17 | private const string SqlAzureServerPrefix = "SQLAZURECONNSTR_";
18 | private const string SqlServerPrefix = "SQLCONNSTR_";
19 | private const string CustomPrefix = "CUSTOMCONNSTR_";
20 |
21 | private const string ConnStrKeyFormat = "ConnectionStrings:{0}";
22 | private const string ProviderKeyFormat = "ConnectionStrings:{0}_ProviderName";
23 |
24 | private readonly string _prefix;
25 |
26 | ///
27 | /// Initializes a new instance.
28 | ///
29 | public EnvironmentVariablesConfigurationProvider() : this(string.Empty)
30 | { }
31 |
32 | ///
33 | /// Initializes a new instance with the specified prefix.
34 | ///
35 | /// A prefix used to filter the environment variables.
36 | public EnvironmentVariablesConfigurationProvider(string prefix)
37 | {
38 | _prefix = prefix ?? string.Empty;
39 | }
40 |
41 | ///
42 | /// Loads the environment variables.
43 | ///
44 | public override void Load()
45 | {
46 | Load(Environment.GetEnvironmentVariables());
47 | }
48 |
49 | internal void Load(IDictionary envVariables)
50 | {
51 | Data = new Dictionary(StringComparer.OrdinalIgnoreCase);
52 |
53 | var filteredEnvVariables = envVariables
54 | .Cast()
55 | .SelectMany(AzureEnvToAppEnv)
56 | .Where(entry => ((string)entry.Key).StartsWith(_prefix, StringComparison.OrdinalIgnoreCase));
57 |
58 | foreach (var envVariable in filteredEnvVariables)
59 | {
60 | var key = ((string)envVariable.Key).Substring(_prefix.Length);
61 | Data[key] = (string)envVariable.Value;
62 | }
63 | }
64 |
65 | private static string NormalizeKey(string key)
66 | {
67 | return key.Replace("__", ConfigurationPath.KeyDelimiter);
68 | }
69 |
70 | private static IEnumerable AzureEnvToAppEnv(DictionaryEntry entry)
71 | {
72 | var key = (string)entry.Key;
73 | var prefix = string.Empty;
74 | var provider = string.Empty;
75 |
76 | if (key.StartsWith(MySqlServerPrefix, StringComparison.OrdinalIgnoreCase))
77 | {
78 | prefix = MySqlServerPrefix;
79 | provider = "MySql.Data.MySqlClient";
80 | }
81 | else if (key.StartsWith(SqlAzureServerPrefix, StringComparison.OrdinalIgnoreCase))
82 | {
83 | prefix = SqlAzureServerPrefix;
84 | provider = "System.Data.SqlClient";
85 | }
86 | else if (key.StartsWith(SqlServerPrefix, StringComparison.OrdinalIgnoreCase))
87 | {
88 | prefix = SqlServerPrefix;
89 | provider = "System.Data.SqlClient";
90 | }
91 | else if (key.StartsWith(CustomPrefix, StringComparison.OrdinalIgnoreCase))
92 | {
93 | prefix = CustomPrefix;
94 | }
95 | else
96 | {
97 | entry.Key = NormalizeKey(key);
98 | yield return entry;
99 | yield break;
100 | }
101 |
102 | // Return the key-value pair for connection string
103 | yield return new DictionaryEntry(
104 | string.Format(ConnStrKeyFormat, NormalizeKey(key.Substring(prefix.Length))),
105 | entry.Value);
106 |
107 | if (!string.IsNullOrEmpty(provider))
108 | {
109 | // Return the key-value pair for provider name
110 | yield return new DictionaryEntry(
111 | string.Format(ProviderKeyFormat, NormalizeKey(key.Substring(prefix.Length))),
112 | provider);
113 | }
114 | }
115 | }
116 | }
117 |
--------------------------------------------------------------------------------
/src/Config.EnvironmentVariables/EnvironmentVariablesConfigurationSource.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) .NET Foundation. All rights reserved.
2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3 |
4 | namespace Microsoft.Extensions.Configuration.EnvironmentVariables
5 | {
6 | ///
7 | /// Represents environment variables as an .
8 | ///
9 | public class EnvironmentVariablesConfigurationSource : IConfigurationSource
10 | {
11 | ///
12 | /// A prefix used to filter environment variables.
13 | ///
14 | public string Prefix { get; set; }
15 |
16 | ///
17 | /// Builds the for this source.
18 | ///
19 | /// The .
20 | /// A
21 | public IConfigurationProvider Build(IConfigurationBuilder builder)
22 | {
23 | return new EnvironmentVariablesConfigurationProvider(Prefix);
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/Config.EnvironmentVariables/EnvironmentVariablesExtensions.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) .NET Foundation. All rights reserved.
2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3 |
4 | using System;
5 | using Microsoft.Extensions.Configuration.EnvironmentVariables;
6 |
7 | namespace Microsoft.Extensions.Configuration
8 | {
9 | ///
10 | /// Extension methods for registering with .
11 | ///
12 | public static class EnvironmentVariablesExtensions
13 | {
14 | ///
15 | /// Adds an that reads configuration values from environment variables.
16 | ///
17 | /// The to add to.
18 | /// The .
19 | public static IConfigurationBuilder AddEnvironmentVariables(this IConfigurationBuilder configurationBuilder)
20 | {
21 | configurationBuilder.Add(new EnvironmentVariablesConfigurationSource());
22 | return configurationBuilder;
23 | }
24 |
25 | ///
26 | /// Adds an that reads configuration values from environment variables
27 | /// with a specified prefix.
28 | ///
29 | /// The to add to.
30 | /// The prefix that environment variable names must start with. The prefix will be removed from the environment variable names.
31 | /// The .
32 | public static IConfigurationBuilder AddEnvironmentVariables(
33 | this IConfigurationBuilder configurationBuilder,
34 | string prefix)
35 | {
36 | configurationBuilder.Add(new EnvironmentVariablesConfigurationSource { Prefix = prefix });
37 | return configurationBuilder;
38 | }
39 |
40 | ///
41 | /// Adds an that reads configuration values from environment variables.
42 | ///
43 | /// The to add to.
44 | /// Configures the source.
45 | /// The .
46 | public static IConfigurationBuilder AddEnvironmentVariables(this IConfigurationBuilder builder, Action configureSource)
47 | => builder.Add(configureSource);
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/src/Config.EnvironmentVariables/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) .NET Foundation. All rights reserved.
2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3 |
4 | using System.Runtime.CompilerServices;
5 |
6 | [assembly: InternalsVisibleTo("Microsoft.Extensions.Configuration.EnvironmentVariables.Test, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
7 |
8 |
--------------------------------------------------------------------------------
/src/Config.FileExtensions/Config.FileExtensions.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Microsoft.Extensions.Configuration.FileExtensions
5 | Microsoft.Extensions.Configuration.FileExtensions
6 | Extension methods for configuring file-based configuration providers for Microsoft.Extensions.Configuration.
7 | netstandard2.0
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/src/Config.FileExtensions/FileConfigurationExtensions.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) .NET Foundation. All rights reserved.
2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3 |
4 | using System;
5 | using Microsoft.Extensions.FileProviders;
6 |
7 | namespace Microsoft.Extensions.Configuration
8 | {
9 | ///
10 | /// Extension methods for .
11 | ///
12 | public static class FileConfigurationExtensions
13 | {
14 | private static string FileProviderKey = "FileProvider";
15 | private static string FileLoadExceptionHandlerKey = "FileLoadExceptionHandler";
16 |
17 | ///
18 | /// Sets the default to be used for file-based providers.
19 | ///
20 | /// The to add to.
21 | /// The default file provider instance.
22 | /// The .
23 | public static IConfigurationBuilder SetFileProvider(this IConfigurationBuilder builder, IFileProvider fileProvider)
24 | {
25 | if (builder == null)
26 | {
27 | throw new ArgumentNullException(nameof(builder));
28 | }
29 |
30 | builder.Properties[FileProviderKey] = fileProvider ?? throw new ArgumentNullException(nameof(fileProvider));
31 | return builder;
32 | }
33 |
34 | ///
35 | /// Gets the default to be used for file-based providers.
36 | ///
37 | /// The .
38 | /// The .
39 | public static IFileProvider GetFileProvider(this IConfigurationBuilder builder)
40 | {
41 | if (builder == null)
42 | {
43 | throw new ArgumentNullException(nameof(builder));
44 | }
45 |
46 | if (builder.Properties.TryGetValue(FileProviderKey, out object provider))
47 | {
48 | return builder.Properties[FileProviderKey] as IFileProvider;
49 | }
50 |
51 | return new PhysicalFileProvider(AppContext.BaseDirectory ?? string.Empty);
52 | }
53 |
54 | ///
55 | /// Sets the FileProvider for file-based providers to a PhysicalFileProvider with the base path.
56 | ///
57 | /// The to add to.
58 | /// The absolute path of file-based providers.
59 | /// The .
60 | public static IConfigurationBuilder SetBasePath(this IConfigurationBuilder builder, string basePath)
61 | {
62 | if (builder == null)
63 | {
64 | throw new ArgumentNullException(nameof(builder));
65 | }
66 |
67 | if (basePath == null)
68 | {
69 | throw new ArgumentNullException(nameof(basePath));
70 | }
71 |
72 | return builder.SetFileProvider(new PhysicalFileProvider(basePath));
73 | }
74 |
75 | ///
76 | /// Sets a default action to be invoked for file-based providers when an error occurs.
77 | ///
78 | /// The to add to.
79 | /// The Action to be invoked on a file load exception.
80 | /// The .
81 | public static IConfigurationBuilder SetFileLoadExceptionHandler(this IConfigurationBuilder builder, Action handler)
82 | {
83 | if (builder == null)
84 | {
85 | throw new ArgumentNullException(nameof(builder));
86 | }
87 |
88 | builder.Properties[FileLoadExceptionHandlerKey] = handler;
89 | return builder;
90 | }
91 |
92 | ///
93 | /// Gets the default to be used for file-based providers.
94 | ///
95 | /// The .
96 | /// The .
97 | public static Action GetFileLoadExceptionHandler(this IConfigurationBuilder builder)
98 | {
99 | if (builder == null)
100 | {
101 | throw new ArgumentNullException(nameof(builder));
102 | }
103 |
104 | if (builder.Properties.TryGetValue(FileLoadExceptionHandlerKey, out object handler))
105 | {
106 | return builder.Properties[FileLoadExceptionHandlerKey] as Action;
107 | }
108 | return null;
109 | }
110 | }
111 | }
--------------------------------------------------------------------------------
/src/Config.FileExtensions/FileConfigurationProvider.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) .NET Foundation. All rights reserved.
2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3 |
4 | using System;
5 | using System.Collections.Generic;
6 | using System.IO;
7 | using System.Text;
8 | using System.Threading;
9 | using Microsoft.Extensions.Primitives;
10 |
11 | namespace Microsoft.Extensions.Configuration
12 | {
13 | ///
14 | /// Base class for file based .
15 | ///
16 | public abstract class FileConfigurationProvider : ConfigurationProvider
17 | {
18 | ///
19 | /// Initializes a new instance with the specified source.
20 | ///
21 | /// The source settings.
22 | public FileConfigurationProvider(FileConfigurationSource source)
23 | {
24 | if (source == null)
25 | {
26 | throw new ArgumentNullException(nameof(source));
27 | }
28 | Source = source;
29 |
30 | if (Source.ReloadOnChange && Source.FileProvider != null)
31 | {
32 | ChangeToken.OnChange(
33 | () => Source.FileProvider.Watch(Source.Path),
34 | () => {
35 | Thread.Sleep(Source.ReloadDelay);
36 | Load(reload: true);
37 | });
38 | }
39 | }
40 |
41 | ///
42 | /// The source settings for this provider.
43 | ///
44 | public FileConfigurationSource Source { get; }
45 |
46 | private void Load(bool reload)
47 | {
48 | var file = Source.FileProvider?.GetFileInfo(Source.Path);
49 | if (file == null || !file.Exists)
50 | {
51 | if (Source.Optional || reload) // Always optional on reload
52 | {
53 | Data = new Dictionary(StringComparer.OrdinalIgnoreCase);
54 | }
55 | else
56 | {
57 | var error = new StringBuilder($"The configuration file '{Source.Path}' was not found and is not optional.");
58 | if (!string.IsNullOrEmpty(file?.PhysicalPath))
59 | {
60 | error.Append($" The physical path is '{file.PhysicalPath}'.");
61 | }
62 | throw new FileNotFoundException(error.ToString());
63 | }
64 | }
65 | else
66 | {
67 | // Always create new Data on reload to drop old keys
68 | if (reload)
69 | {
70 | Data = new Dictionary(StringComparer.OrdinalIgnoreCase);
71 | }
72 | using (var stream = file.CreateReadStream())
73 | {
74 | try
75 | {
76 | Load(stream);
77 | }
78 | catch (Exception e)
79 | {
80 | bool ignoreException = false;
81 | if (Source.OnLoadException != null)
82 | {
83 | var exceptionContext = new FileLoadExceptionContext
84 | {
85 | Provider = this,
86 | Exception = e
87 | };
88 | Source.OnLoadException.Invoke(exceptionContext);
89 | ignoreException = exceptionContext.Ignore;
90 | }
91 | if (!ignoreException)
92 | {
93 | throw e;
94 | }
95 | }
96 | }
97 | }
98 | // REVIEW: Should we raise this in the base as well / instead?
99 | OnReload();
100 | }
101 |
102 | ///
103 | /// Loads the contents of the file at .
104 | ///
105 | /// If Optional is false on the source and a
106 | /// file does not exist at specified Path.
107 | public override void Load()
108 | {
109 | Load(reload: false);
110 | }
111 |
112 | ///
113 | /// Loads this provider's data from a stream.
114 | ///
115 | /// The stream to read.
116 | public abstract void Load(Stream stream);
117 | }
118 | }
119 |
--------------------------------------------------------------------------------
/src/Config.FileExtensions/FileConfigurationSource.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) .NET Foundation. All rights reserved.
2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3 |
4 | using System;
5 | using System.IO;
6 | using Microsoft.Extensions.FileProviders;
7 |
8 | namespace Microsoft.Extensions.Configuration
9 | {
10 | ///
11 | /// Represents a base class for file based .
12 | ///
13 | public abstract class FileConfigurationSource : IConfigurationSource
14 | {
15 | ///
16 | /// Used to access the contents of the file.
17 | ///
18 | public IFileProvider FileProvider { get; set; }
19 |
20 | ///
21 | /// The path to the file.
22 | ///
23 | public string Path { get; set; }
24 |
25 | ///
26 | /// Determines if loading the file is optional.
27 | ///
28 | public bool Optional { get; set; }
29 |
30 | ///
31 | /// Determines whether the source will be loaded if the underlying file changes.
32 | ///
33 | public bool ReloadOnChange { get; set; }
34 |
35 | ///
36 | /// Number of milliseconds that reload will wait before calling Load. This helps
37 | /// avoid triggering reload before a file is completely written. Default is 250.
38 | ///
39 | public int ReloadDelay { get; set; } = 250;
40 |
41 | ///
42 | /// Will be called if an uncaught exception occurs in FileConfigurationProvider.Load.
43 | ///
44 | public Action OnLoadException { get; set; }
45 |
46 | ///
47 | /// Builds the for this source.
48 | ///
49 | /// The .
50 | /// A
51 | public abstract IConfigurationProvider Build(IConfigurationBuilder builder);
52 |
53 | ///
54 | /// Called to use any default settings on the builder like the FileProvider or FileLoadExceptionHandler.
55 | ///
56 | /// The .
57 | public void EnsureDefaults(IConfigurationBuilder builder)
58 | {
59 | FileProvider = FileProvider ?? builder.GetFileProvider();
60 | OnLoadException = OnLoadException ?? builder.GetFileLoadExceptionHandler();
61 | }
62 |
63 | ///
64 | /// If no file provider has been set, for absolute Path, this will creates a physical file provider
65 | /// for the nearest existing directory.
66 | ///
67 | public void ResolveFileProvider()
68 | {
69 | if (FileProvider == null &&
70 | !string.IsNullOrEmpty(Path) &&
71 | System.IO.Path.IsPathRooted(Path))
72 | {
73 | var directory = System.IO.Path.GetDirectoryName(Path);
74 | var pathToFile = System.IO.Path.GetFileName(Path);
75 | while (!string.IsNullOrEmpty(directory) && !Directory.Exists(directory))
76 | {
77 | pathToFile = System.IO.Path.Combine(System.IO.Path.GetFileName(directory), pathToFile);
78 | directory = System.IO.Path.GetDirectoryName(directory);
79 | }
80 | if (Directory.Exists(directory))
81 | {
82 | FileProvider = new PhysicalFileProvider(directory);
83 | Path = pathToFile;
84 | }
85 | }
86 | }
87 |
88 | }
89 | }
--------------------------------------------------------------------------------
/src/Config.FileExtensions/FileLoadExceptionContext.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) .NET Foundation. All rights reserved.
2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3 |
4 | using System;
5 |
6 | namespace Microsoft.Extensions.Configuration
7 | {
8 | ///
9 | /// Contains information about a file load exception.
10 | ///
11 | public class FileLoadExceptionContext
12 | {
13 | ///
14 | /// The that caused the exception.
15 | ///
16 | public FileConfigurationProvider Provider { get; set; }
17 |
18 | ///
19 | /// The exception that occured in Load.
20 | ///
21 | public Exception Exception { get; set; }
22 |
23 | ///
24 | /// If true, the exception will not be rethrown.
25 | ///
26 | public bool Ignore { get; set; }
27 | }
28 | }
--------------------------------------------------------------------------------
/src/Config.FileExtensions/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) .NET Foundation. All rights reserved.
2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3 |
4 | using System.Runtime.CompilerServices;
5 |
6 | [assembly: InternalsVisibleTo("Microsoft.Extensions.Configuration.FileExtensions.Test, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
7 |
8 |
--------------------------------------------------------------------------------
/src/Config.FileExtensions/Properties/Resources.Designer.cs:
--------------------------------------------------------------------------------
1 | //
2 | namespace Microsoft.Extensions.Configuration.FileExtensions
3 | {
4 | using System.Globalization;
5 | using System.Reflection;
6 | using System.Resources;
7 |
8 | internal static class Resources
9 | {
10 | private static readonly ResourceManager _resourceManager
11 | = new ResourceManager("Microsoft.Extensions.Configuration.FileExtensions.Resources", typeof(Resources).GetTypeInfo().Assembly);
12 |
13 | ///
14 | /// The expected physical path was '{0}'.
15 | ///
16 | internal static string Error_ExpectedPhysicalPath
17 | {
18 | get => GetString("Error_ExpectedPhysicalPath");
19 | }
20 |
21 | ///
22 | /// The expected physical path was '{0}'.
23 | ///
24 | internal static string FormatError_ExpectedPhysicalPath(object p0)
25 | => string.Format(CultureInfo.CurrentCulture, GetString("Error_ExpectedPhysicalPath"), p0);
26 |
27 | ///
28 | /// The configuration file '{0}' was not found and is not optional.
29 | ///
30 | internal static string Error_FileNotFound
31 | {
32 | get => GetString("Error_FileNotFound");
33 | }
34 |
35 | ///
36 | /// The configuration file '{0}' was not found and is not optional.
37 | ///
38 | internal static string FormatError_FileNotFound(object p0)
39 | => string.Format(CultureInfo.CurrentCulture, GetString("Error_FileNotFound"), p0);
40 |
41 | private static string GetString(string name, params string[] formatterNames)
42 | {
43 | var value = _resourceManager.GetString(name);
44 |
45 | System.Diagnostics.Debug.Assert(value != null);
46 |
47 | if (formatterNames != null)
48 | {
49 | for (var i = 0; i < formatterNames.Length; i++)
50 | {
51 | value = value.Replace("{" + formatterNames[i] + "}", "{" + i + "}");
52 | }
53 | }
54 |
55 | return value;
56 | }
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/src/Config.Ini/Config.Ini.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Microsoft.Extensions.Configuration.Ini
5 | Microsoft.Extensions.Configuration.Ini
6 | INI configuration provider implementation for Microsoft.Extensions.Configuration.
7 | netstandard2.0
8 | $(PackageTags);ini
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/src/Config.Ini/IniConfigurationProvider.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) .NET Foundation. All rights reserved.
2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3 |
4 | using System;
5 | using System.Collections.Generic;
6 | using System.IO;
7 |
8 | namespace Microsoft.Extensions.Configuration.Ini
9 | {
10 | ///
11 | /// An INI file based .
12 | /// Files are simple line structures (INI Files on Wikipedia)
13 | ///
14 | ///
15 | /// [Section:Header]
16 | /// key1=value1
17 | /// key2 = " value2 "
18 | /// ; comment
19 | /// # comment
20 | /// / comment
21 | ///
22 | public class IniConfigurationProvider : FileConfigurationProvider
23 | {
24 | ///
25 | /// Initializes a new instance with the specified source.
26 | ///
27 | /// The source settings.
28 | public IniConfigurationProvider(IniConfigurationSource source) : base(source) { }
29 |
30 | ///
31 | /// Loads the INI data from a stream.
32 | ///
33 | /// The stream to read.
34 | public override void Load(Stream stream)
35 | {
36 | var data = new Dictionary(StringComparer.OrdinalIgnoreCase);
37 |
38 | using (var reader = new StreamReader(stream))
39 | {
40 | var sectionPrefix = string.Empty;
41 |
42 | while (reader.Peek() != -1)
43 | {
44 | var rawLine = reader.ReadLine();
45 | var line = rawLine.Trim();
46 |
47 | // Ignore blank lines
48 | if (string.IsNullOrWhiteSpace(line))
49 | {
50 | continue;
51 | }
52 | // Ignore comments
53 | if (line[0] == ';' || line[0] == '#' || line[0] == '/')
54 | {
55 | continue;
56 | }
57 | // [Section:header]
58 | if (line[0] == '[' && line[line.Length - 1] == ']')
59 | {
60 | // remove the brackets
61 | sectionPrefix = line.Substring(1, line.Length - 2) + ConfigurationPath.KeyDelimiter;
62 | continue;
63 | }
64 |
65 | // key = value OR "value"
66 | int separator = line.IndexOf('=');
67 | if (separator < 0)
68 | {
69 | throw new FormatException(Resources.FormatError_UnrecognizedLineFormat(rawLine));
70 | }
71 |
72 | string key = sectionPrefix + line.Substring(0, separator).Trim();
73 | string value = line.Substring(separator + 1).Trim();
74 |
75 | // Remove quotes
76 | if (value.Length > 1 && value[0] == '"' && value[value.Length - 1] == '"')
77 | {
78 | value = value.Substring(1, value.Length - 2);
79 | }
80 |
81 | if (data.ContainsKey(key))
82 | {
83 | throw new FormatException(Resources.FormatError_KeyIsDuplicated(key));
84 | }
85 |
86 | data[key] = value;
87 | }
88 | }
89 |
90 | Data = data;
91 | }
92 | }
93 | }
94 |
--------------------------------------------------------------------------------
/src/Config.Ini/IniConfigurationSource.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) .NET Foundation. All rights reserved.
2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3 |
4 | namespace Microsoft.Extensions.Configuration.Ini
5 | {
6 | ///
7 | /// Represents an INI file as an .
8 | /// Files are simple line structures (INI Files on Wikipedia)
9 | ///
10 | ///
11 | /// [Section:Header]
12 | /// key1=value1
13 | /// key2 = " value2 "
14 | /// ; comment
15 | /// # comment
16 | /// / comment
17 | ///
18 | public class IniConfigurationSource : FileConfigurationSource
19 | {
20 | ///
21 | /// Builds the for this source.
22 | ///
23 | /// The .
24 | /// An
25 | public override IConfigurationProvider Build(IConfigurationBuilder builder)
26 | {
27 | EnsureDefaults(builder);
28 | return new IniConfigurationProvider(this);
29 | }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/Config.Ini/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) .NET Foundation. All rights reserved.
2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3 |
4 | using System.Runtime.CompilerServices;
5 |
6 | [assembly: InternalsVisibleTo("Microsoft.Extensions.Configuration.Ini.Test, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
7 |
8 |
--------------------------------------------------------------------------------
/src/Config.Ini/Properties/Resources.Designer.cs:
--------------------------------------------------------------------------------
1 | //
2 | namespace Microsoft.Extensions.Configuration.Ini
3 | {
4 | using System.Globalization;
5 | using System.Reflection;
6 | using System.Resources;
7 |
8 | internal static class Resources
9 | {
10 | private static readonly ResourceManager _resourceManager
11 | = new ResourceManager("Microsoft.Extensions.Configuration.Ini.Resources", typeof(Resources).GetTypeInfo().Assembly);
12 |
13 | ///
14 | /// File path must be a non-empty string.
15 | ///
16 | internal static string Error_InvalidFilePath
17 | {
18 | get => GetString("Error_InvalidFilePath");
19 | }
20 |
21 | ///
22 | /// File path must be a non-empty string.
23 | ///
24 | internal static string FormatError_InvalidFilePath()
25 | => GetString("Error_InvalidFilePath");
26 |
27 | ///
28 | /// A duplicate key '{0}' was found.
29 | ///
30 | internal static string Error_KeyIsDuplicated
31 | {
32 | get => GetString("Error_KeyIsDuplicated");
33 | }
34 |
35 | ///
36 | /// A duplicate key '{0}' was found.
37 | ///
38 | internal static string FormatError_KeyIsDuplicated(object p0)
39 | => string.Format(CultureInfo.CurrentCulture, GetString("Error_KeyIsDuplicated"), p0);
40 |
41 | ///
42 | /// Unrecognized line format: '{0}'.
43 | ///
44 | internal static string Error_UnrecognizedLineFormat
45 | {
46 | get => GetString("Error_UnrecognizedLineFormat");
47 | }
48 |
49 | ///
50 | /// Unrecognized line format: '{0}'.
51 | ///
52 | internal static string FormatError_UnrecognizedLineFormat(object p0)
53 | => string.Format(CultureInfo.CurrentCulture, GetString("Error_UnrecognizedLineFormat"), p0);
54 |
55 | private static string GetString(string name, params string[] formatterNames)
56 | {
57 | var value = _resourceManager.GetString(name);
58 |
59 | System.Diagnostics.Debug.Assert(value != null);
60 |
61 | if (formatterNames != null)
62 | {
63 | for (var i = 0; i < formatterNames.Length; i++)
64 | {
65 | value = value.Replace("{" + formatterNames[i] + "}", "{" + i + "}");
66 | }
67 | }
68 |
69 | return value;
70 | }
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/src/Config.Json/Config.Json.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Microsoft.Extensions.Configuration.Json
5 | Microsoft.Extensions.Configuration.Json
6 | JSON configuration provider implementation for Microsoft.Extensions.Configuration.
7 | netstandard2.0
8 | $(PackageTags);json
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/src/Config.Json/JsonConfigurationFileParser.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) .NET Foundation. All rights reserved.
2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3 |
4 | using System;
5 | using System.Collections.Generic;
6 | using System.Globalization;
7 | using System.IO;
8 | using System.Linq;
9 | using Newtonsoft.Json;
10 | using Newtonsoft.Json.Linq;
11 |
12 | namespace Microsoft.Extensions.Configuration.Json
13 | {
14 | internal class JsonConfigurationFileParser
15 | {
16 | private JsonConfigurationFileParser() { }
17 |
18 | private readonly IDictionary _data = new SortedDictionary(StringComparer.OrdinalIgnoreCase);
19 | private readonly Stack _context = new Stack();
20 | private string _currentPath;
21 |
22 | private JsonTextReader _reader;
23 |
24 | public static IDictionary Parse(Stream input)
25 | => new JsonConfigurationFileParser().ParseStream(input);
26 |
27 | private IDictionary ParseStream(Stream input)
28 | {
29 | _data.Clear();
30 | _reader = new JsonTextReader(new StreamReader(input));
31 | _reader.DateParseHandling = DateParseHandling.None;
32 |
33 | var jsonConfig = JObject.Load(_reader);
34 |
35 | VisitJObject(jsonConfig);
36 |
37 | return _data;
38 | }
39 |
40 | private void VisitJObject(JObject jObject)
41 | {
42 | foreach (var property in jObject.Properties())
43 | {
44 | EnterContext(property.Name);
45 | VisitProperty(property);
46 | ExitContext();
47 | }
48 | }
49 |
50 | private void VisitProperty(JProperty property)
51 | {
52 | VisitToken(property.Value);
53 | }
54 |
55 | private void VisitToken(JToken token)
56 | {
57 | switch (token.Type)
58 | {
59 | case JTokenType.Object:
60 | VisitJObject(token.Value());
61 | break;
62 |
63 | case JTokenType.Array:
64 | VisitArray(token.Value());
65 | break;
66 |
67 | case JTokenType.Integer:
68 | case JTokenType.Float:
69 | case JTokenType.String:
70 | case JTokenType.Boolean:
71 | case JTokenType.Bytes:
72 | case JTokenType.Raw:
73 | case JTokenType.Null:
74 | VisitPrimitive(token.Value());
75 | break;
76 |
77 | default:
78 | throw new FormatException(Resources.FormatError_UnsupportedJSONToken(
79 | _reader.TokenType,
80 | _reader.Path,
81 | _reader.LineNumber,
82 | _reader.LinePosition));
83 | }
84 | }
85 |
86 | private void VisitArray(JArray array)
87 | {
88 | for (int index = 0; index < array.Count; index++)
89 | {
90 | EnterContext(index.ToString());
91 | VisitToken(array[index]);
92 | ExitContext();
93 | }
94 | }
95 |
96 | private void VisitPrimitive(JValue data)
97 | {
98 | var key = _currentPath;
99 |
100 | if (_data.ContainsKey(key))
101 | {
102 | throw new FormatException(Resources.FormatError_KeyIsDuplicated(key));
103 | }
104 | _data[key] = data.ToString(CultureInfo.InvariantCulture);
105 | }
106 |
107 | private void EnterContext(string context)
108 | {
109 | _context.Push(context);
110 | _currentPath = ConfigurationPath.Combine(_context.Reverse());
111 | }
112 |
113 | private void ExitContext()
114 | {
115 | _context.Pop();
116 | _currentPath = ConfigurationPath.Combine(_context.Reverse());
117 | }
118 | }
119 | }
120 |
--------------------------------------------------------------------------------
/src/Config.Json/JsonConfigurationProvider.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) .NET Foundation. All rights reserved.
2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3 |
4 | using System;
5 | using System.Collections.Generic;
6 | using System.IO;
7 | using System.Linq;
8 | using Newtonsoft.Json;
9 |
10 | namespace Microsoft.Extensions.Configuration.Json
11 | {
12 | ///
13 | /// A JSON file based .
14 | ///
15 | public class JsonConfigurationProvider : FileConfigurationProvider
16 | {
17 | ///
18 | /// Initializes a new instance with the specified source.
19 | ///
20 | /// The source settings.
21 | public JsonConfigurationProvider(JsonConfigurationSource source) : base(source) { }
22 |
23 | ///
24 | /// Loads the JSON data from a stream.
25 | ///
26 | /// The stream to read.
27 | public override void Load(Stream stream)
28 | {
29 | try
30 | {
31 | Data = JsonConfigurationFileParser.Parse(stream);
32 | }
33 | catch (JsonReaderException e)
34 | {
35 | string errorLine = string.Empty;
36 | if (stream.CanSeek)
37 | {
38 | stream.Seek(0, SeekOrigin.Begin);
39 |
40 | IEnumerable fileContent;
41 | using (var streamReader = new StreamReader(stream))
42 | {
43 | fileContent = ReadLines(streamReader);
44 | errorLine = RetrieveErrorContext(e, fileContent);
45 | }
46 | }
47 |
48 | throw new FormatException(Resources.FormatError_JSONParseError(e.LineNumber, errorLine), e);
49 | }
50 | }
51 |
52 | private static string RetrieveErrorContext(JsonReaderException e, IEnumerable fileContent)
53 | {
54 | string errorLine = null;
55 | if (e.LineNumber >= 2)
56 | {
57 | var errorContext = fileContent.Skip(e.LineNumber - 2).Take(2).ToList();
58 | // Handle situations when the line number reported is out of bounds
59 | if (errorContext.Count() >= 2)
60 | {
61 | errorLine = errorContext[0].Trim() + Environment.NewLine + errorContext[1].Trim();
62 | }
63 | }
64 | if (string.IsNullOrEmpty(errorLine))
65 | {
66 | var possibleLineContent = fileContent.Skip(e.LineNumber - 1).FirstOrDefault();
67 | errorLine = possibleLineContent ?? string.Empty;
68 | }
69 | return errorLine;
70 | }
71 |
72 | private static IEnumerable ReadLines(StreamReader streamReader)
73 | {
74 | string line;
75 | do
76 | {
77 | line = streamReader.ReadLine();
78 | yield return line;
79 | } while (line != null);
80 | }
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/src/Config.Json/JsonConfigurationSource.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) .NET Foundation. All rights reserved.
2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3 |
4 | using System;
5 |
6 | namespace Microsoft.Extensions.Configuration.Json
7 | {
8 | ///
9 | /// Represents a JSON file as an .
10 | ///
11 | public class JsonConfigurationSource : FileConfigurationSource
12 | {
13 | ///
14 | /// Builds the for this source.
15 | ///
16 | /// The .
17 | /// A
18 | public override IConfigurationProvider Build(IConfigurationBuilder builder)
19 | {
20 | EnsureDefaults(builder);
21 | return new JsonConfigurationProvider(this);
22 | }
23 | }
24 | }
--------------------------------------------------------------------------------
/src/Config.Json/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) .NET Foundation. All rights reserved.
2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3 |
4 | using System.Runtime.CompilerServices;
5 |
6 | [assembly: InternalsVisibleTo("Microsoft.Extensions.Configuration.Json.Test, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
7 |
8 |
--------------------------------------------------------------------------------
/src/Config.Json/Properties/Resources.Designer.cs:
--------------------------------------------------------------------------------
1 | //
2 | namespace Microsoft.Extensions.Configuration.Json
3 | {
4 | using System.Globalization;
5 | using System.Reflection;
6 | using System.Resources;
7 |
8 | internal static class Resources
9 | {
10 | private static readonly ResourceManager _resourceManager
11 | = new ResourceManager("Microsoft.Extensions.Configuration.Json.Resources", typeof(Resources).GetTypeInfo().Assembly);
12 |
13 | ///
14 | /// File path must be a non-empty string.
15 | ///
16 | internal static string Error_InvalidFilePath
17 | {
18 | get => GetString("Error_InvalidFilePath");
19 | }
20 |
21 | ///
22 | /// File path must be a non-empty string.
23 | ///
24 | internal static string FormatError_InvalidFilePath()
25 | => GetString("Error_InvalidFilePath");
26 |
27 | ///
28 | /// Could not parse the JSON file. Error on line number '{0}': '{1}'.
29 | ///
30 | internal static string Error_JSONParseError
31 | {
32 | get => GetString("Error_JSONParseError");
33 | }
34 |
35 | ///
36 | /// Could not parse the JSON file. Error on line number '{0}': '{1}'.
37 | ///
38 | internal static string FormatError_JSONParseError(object p0, object p1)
39 | => string.Format(CultureInfo.CurrentCulture, GetString("Error_JSONParseError"), p0, p1);
40 |
41 | ///
42 | /// A duplicate key '{0}' was found.
43 | ///
44 | internal static string Error_KeyIsDuplicated
45 | {
46 | get => GetString("Error_KeyIsDuplicated");
47 | }
48 |
49 | ///
50 | /// A duplicate key '{0}' was found.
51 | ///
52 | internal static string FormatError_KeyIsDuplicated(object p0)
53 | => string.Format(CultureInfo.CurrentCulture, GetString("Error_KeyIsDuplicated"), p0);
54 |
55 | ///
56 | /// Unsupported JSON token '{0}' was found. Path '{1}', line {2} position {3}.
57 | ///
58 | internal static string Error_UnsupportedJSONToken
59 | {
60 | get => GetString("Error_UnsupportedJSONToken");
61 | }
62 |
63 | ///
64 | /// Unsupported JSON token '{0}' was found. Path '{1}', line {2} position {3}.
65 | ///
66 | internal static string FormatError_UnsupportedJSONToken(object p0, object p1, object p2, object p3)
67 | => string.Format(CultureInfo.CurrentCulture, GetString("Error_UnsupportedJSONToken"), p0, p1, p2, p3);
68 |
69 | private static string GetString(string name, params string[] formatterNames)
70 | {
71 | var value = _resourceManager.GetString(name);
72 |
73 | System.Diagnostics.Debug.Assert(value != null);
74 |
75 | if (formatterNames != null)
76 | {
77 | for (var i = 0; i < formatterNames.Length; i++)
78 | {
79 | value = value.Replace("{" + formatterNames[i] + "}", "{" + i + "}");
80 | }
81 | }
82 |
83 | return value;
84 | }
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/src/Config.KeyPerFile/Config.KeyPerFile.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Microsoft.Extensions.Configuration.KeyPerFile
5 | Microsoft.Extensions.Configuration.KeyPerFile
6 | Configuration provider that uses files in a directory for Microsoft.Extensions.Configuration.
7 | netstandard2.0
8 | false
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/src/Config.KeyPerFile/KeyPerFileConfigurationBuilderExtensions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 | using Microsoft.Extensions.Configuration.KeyPerFile;
4 | using Microsoft.Extensions.FileProviders;
5 |
6 | namespace Microsoft.Extensions.Configuration
7 | {
8 | ///
9 | /// Extension methods for registering with .
10 | ///
11 | public static class KeyPerFileConfigurationBuilderExtensions
12 | {
13 | ///
14 | /// Adds configuration using files from a directory. File names are used as the key,
15 | /// file contents are used as the value.
16 | ///
17 | /// The to add to.
18 | /// The path to the directory.
19 | /// Whether the directory is optional.
20 | /// The .
21 | public static IConfigurationBuilder AddKeyPerFile(this IConfigurationBuilder builder, string directoryPath, bool optional)
22 | => builder.AddKeyPerFile(source =>
23 | {
24 | // Only try to set the file provider if its not optional or the directory exists
25 | if (!optional || Directory.Exists(directoryPath))
26 | {
27 | source.FileProvider = new PhysicalFileProvider(directoryPath);
28 | }
29 | source.Optional = optional;
30 | });
31 |
32 | ///
33 | /// Adds configuration using files from a directory. File names are used as the key,
34 | /// file contents are used as the value.
35 | ///
36 | /// The to add to.
37 | /// Configures the source.
38 | /// The .
39 | public static IConfigurationBuilder AddKeyPerFile(this IConfigurationBuilder builder, Action configureSource)
40 | => builder.Add(configureSource);
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/Config.KeyPerFile/KeyPerFileConfigurationProvider.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 |
5 | namespace Microsoft.Extensions.Configuration.KeyPerFile
6 | {
7 | ///
8 | /// A that uses a directory's files as configuration key/values.
9 | ///
10 | public class KeyPerFileConfigurationProvider : ConfigurationProvider
11 | {
12 | KeyPerFileConfigurationSource Source { get; set; }
13 |
14 | ///
15 | /// Initializes a new instance.
16 | ///
17 | /// The settings.
18 | public KeyPerFileConfigurationProvider(KeyPerFileConfigurationSource source)
19 | => Source = source ?? throw new ArgumentNullException(nameof(source));
20 |
21 | private static string NormalizeKey(string key)
22 | => key.Replace("__", ConfigurationPath.KeyDelimiter);
23 |
24 | private static string TrimNewLine(string value)
25 | => value.EndsWith(Environment.NewLine)
26 | ? value.Substring(0, value.Length - Environment.NewLine.Length)
27 | : value;
28 |
29 | ///
30 | /// Loads the docker secrets.
31 | ///
32 | public override void Load()
33 | {
34 | Data = new Dictionary(StringComparer.OrdinalIgnoreCase);
35 |
36 | if (Source.FileProvider == null)
37 | {
38 | if (Source.Optional)
39 | {
40 | return;
41 | }
42 | else
43 | {
44 | throw new DirectoryNotFoundException("A non-null file provider for the directory is required when this source is not optional.");
45 | }
46 | }
47 |
48 | var directory = Source.FileProvider.GetDirectoryContents("/");
49 | if (!directory.Exists && !Source.Optional)
50 | {
51 | throw new DirectoryNotFoundException("The root directory for the FileProvider doesn't exist and is not optional.");
52 | }
53 |
54 | foreach (var file in directory)
55 | {
56 | if (file.IsDirectory)
57 | {
58 | continue;
59 | }
60 |
61 | using (var stream = file.CreateReadStream())
62 | using (var streamReader = new StreamReader(stream))
63 | {
64 | if (Source.IgnoreCondition == null || !Source.IgnoreCondition(file.Name))
65 | {
66 | Data.Add(NormalizeKey(file.Name), TrimNewLine(streamReader.ReadToEnd()));
67 | }
68 | }
69 | }
70 | }
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/src/Config.KeyPerFile/KeyPerFileConfigurationSource.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 | using Microsoft.Extensions.FileProviders;
4 |
5 | namespace Microsoft.Extensions.Configuration.KeyPerFile
6 | {
7 | ///
8 | /// An used to configure .
9 | ///
10 | public class KeyPerFileConfigurationSource : IConfigurationSource
11 | {
12 | ///
13 | /// Constructor;
14 | ///
15 | public KeyPerFileConfigurationSource()
16 | => IgnoreCondition = s => IgnorePrefix != null && s.StartsWith(IgnorePrefix);
17 |
18 | ///
19 | /// The FileProvider whos root "/" directory files will be used as configuration data.
20 | ///
21 | public IFileProvider FileProvider { get; set; }
22 |
23 | ///
24 | /// Files that start with this prefix will be excluded.
25 | /// Defaults to "ignore.".
26 | ///
27 | public string IgnorePrefix { get; set; } = "ignore.";
28 |
29 | ///
30 | /// Used to determine if a file should be ignored using its name.
31 | /// Defaults to using the IgnorePrefix.
32 | ///
33 | public Func IgnoreCondition { get; set; }
34 |
35 | ///
36 | /// If false, will throw if the directory doesn't exist.
37 | ///
38 | public bool Optional { get; set; }
39 |
40 | ///
41 | /// Builds the for this source.
42 | ///
43 | /// The .
44 | /// A
45 | public IConfigurationProvider Build(IConfigurationBuilder builder)
46 | => new KeyPerFileConfigurationProvider(this);
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/src/Config.KeyPerFile/README.md:
--------------------------------------------------------------------------------
1 |
2 | This is a configuration provider that uses a directory's files as data. A file's name is the key and the contents are the value.
3 |
--------------------------------------------------------------------------------
/src/Config.UserSecrets/Config.UserSecrets.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Microsoft.Extensions.Configuration.UserSecrets
5 | Microsoft.Extensions.Configuration.UserSecrets
6 | Microsoft.Extensions.Configuration.UserSecrets
7 | User secrets configuration provider implementation for Microsoft.Extensions.Configuration.
8 | netstandard2.0
9 | $(PackageTags);secrets;usersecrets
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/src/Config.UserSecrets/PathHelper.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) .NET Foundation. All rights reserved.
2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3 |
4 | using System;
5 | using System.IO;
6 |
7 | namespace Microsoft.Extensions.Configuration.UserSecrets
8 | {
9 | ///
10 | /// Provides paths for user secrets configuration files.
11 | ///
12 | public class PathHelper
13 | {
14 | internal const string SecretsFileName = "secrets.json";
15 |
16 | ///
17 | ///
18 | /// Returns the path to the JSON file that stores user secrets.
19 | ///
20 | ///
21 | /// This uses the current user profile to locate the secrets file on disk in a location outside of source control.
22 | ///
23 | ///
24 | /// The user secret ID.
25 | /// The full path to the secret file.
26 | public static string GetSecretsPathFromSecretsId(string userSecretsId)
27 | {
28 | if (string.IsNullOrEmpty(userSecretsId))
29 | {
30 | throw new ArgumentException(Resources.Common_StringNullOrEmpty, nameof(userSecretsId));
31 | }
32 |
33 | var badCharIndex = userSecretsId.IndexOfAny(Path.GetInvalidFileNameChars());
34 | if (badCharIndex != -1)
35 | {
36 | throw new InvalidOperationException(
37 | string.Format(
38 | Resources.Error_Invalid_Character_In_UserSecrets_Id,
39 | userSecretsId[badCharIndex],
40 | badCharIndex));
41 | }
42 |
43 | const string userSecretsFallbackDir = "DOTNET_USER_SECRETS_FALLBACK_DIR";
44 |
45 | // For backwards compat, this checks env vars first before using Env.GetFolderPath
46 | var root = Environment.GetEnvironmentVariable("APPDATA") // On Windows it goes to %APPDATA%\Microsoft\UserSecrets\
47 | ?? Environment.GetEnvironmentVariable("HOME") // On Mac/Linux it goes to ~/.microsoft/usersecrets/
48 | ?? Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)
49 | ?? Environment.GetFolderPath(Environment.SpecialFolder.UserProfile)
50 | ?? Environment.GetEnvironmentVariable(userSecretsFallbackDir); // this fallback is an escape hatch if everything else fails
51 |
52 | if (string.IsNullOrEmpty(root))
53 | {
54 | throw new InvalidOperationException("Could not determine an appropriate location for storing user secrets. Set the " + userSecretsFallbackDir + " environment variable to a folder where user secrets should be stored.");
55 | }
56 |
57 | if (!string.IsNullOrEmpty(Environment.GetEnvironmentVariable("APPDATA")))
58 | {
59 | return Path.Combine(root, "Microsoft", "UserSecrets", userSecretsId, SecretsFileName);
60 | }
61 | else
62 | {
63 | return Path.Combine(root, ".microsoft", "usersecrets", userSecretsId, SecretsFileName);
64 | }
65 | }
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/src/Config.UserSecrets/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) .NET Foundation. All rights reserved.
2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3 |
4 | using System.Runtime.CompilerServices;
5 |
6 | [assembly: InternalsVisibleTo("Microsoft.Extensions.Configuration.UserSecrets.Test, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
7 |
--------------------------------------------------------------------------------
/src/Config.UserSecrets/Properties/Resources.Designer.cs:
--------------------------------------------------------------------------------
1 | //
2 | namespace Microsoft.Extensions.Configuration.UserSecrets
3 | {
4 | using System.Globalization;
5 | using System.Reflection;
6 | using System.Resources;
7 |
8 | internal static class Resources
9 | {
10 | private static readonly ResourceManager _resourceManager
11 | = new ResourceManager("Microsoft.Extensions.Configuration.UserSecrets.Resources", typeof(Resources).GetTypeInfo().Assembly);
12 |
13 | ///
14 | /// Value cannot be null or an empty string.
15 | ///
16 | internal static string Common_StringNullOrEmpty
17 | {
18 | get => GetString("Common_StringNullOrEmpty");
19 | }
20 |
21 | ///
22 | /// Value cannot be null or an empty string.
23 | ///
24 | internal static string FormatCommon_StringNullOrEmpty()
25 | => GetString("Common_StringNullOrEmpty");
26 |
27 | ///
28 | /// Invalid character '{0}' found in the user secrets ID at index '{1}'.
29 | ///
30 | internal static string Error_Invalid_Character_In_UserSecrets_Id
31 | {
32 | get => GetString("Error_Invalid_Character_In_UserSecrets_Id");
33 | }
34 |
35 | ///
36 | /// Invalid character '{0}' found in the user secrets ID at index '{1}'.
37 | ///
38 | internal static string FormatError_Invalid_Character_In_UserSecrets_Id(object p0, object p1)
39 | => string.Format(CultureInfo.CurrentCulture, GetString("Error_Invalid_Character_In_UserSecrets_Id"), p0, p1);
40 |
41 | ///
42 | /// Could not find 'UserSecretsIdAttribute' on assembly '{0}'.
43 | /// Check that the project for '{0}' has set the 'UserSecretsId' build property.
44 | /// If the 'UserSecretsId' property is already set then add a reference to the Microsoft.Extensions.Configuration.UserSecrets package.
45 | ///
46 | internal static string Error_Missing_UserSecretsIdAttribute
47 | {
48 | get => GetString("Error_Missing_UserSecretsIdAttribute");
49 | }
50 |
51 | ///
52 | /// Could not find 'UserSecretsIdAttribute' on assembly '{0}'.
53 | /// Check that the project for '{0}' has set the 'UserSecretsId' build property.
54 | /// If the 'UserSecretsId' property is already set then add a reference to the Microsoft.Extensions.Configuration.UserSecrets package.
55 | ///
56 | internal static string FormatError_Missing_UserSecretsIdAttribute(object p0)
57 | => string.Format(CultureInfo.CurrentCulture, GetString("Error_Missing_UserSecretsIdAttribute"), p0);
58 |
59 | private static string GetString(string name, params string[] formatterNames)
60 | {
61 | var value = _resourceManager.GetString(name);
62 |
63 | System.Diagnostics.Debug.Assert(value != null);
64 |
65 | if (formatterNames != null)
66 | {
67 | for (var i = 0; i < formatterNames.Length; i++)
68 | {
69 | value = value.Replace("{" + formatterNames[i] + "}", "{" + i + "}");
70 | }
71 | }
72 |
73 | return value;
74 | }
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/src/Config.UserSecrets/UserSecretsIdAttribute.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) .NET Foundation. All rights reserved.
2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3 |
4 | using System;
5 |
6 | namespace Microsoft.Extensions.Configuration.UserSecrets
7 | {
8 | ///
9 | ///
10 | /// Represents the user secrets ID.
11 | ///
12 | ///
13 | /// In most cases, this attribute is automatically generated during compilation by MSBuild targets
14 | /// included in the UserSecrets NuGet package. These targets use the MSBuild property 'UserSecretsId'
15 | /// to set the value for .
16 | ///
17 | ///
18 | [AttributeUsage(AttributeTargets.Assembly, Inherited = false, AllowMultiple = false)]
19 | public class UserSecretsIdAttribute : Attribute
20 | {
21 | ///
22 | /// Initializes an instance of .
23 | ///
24 | /// The user secrets ID.
25 | public UserSecretsIdAttribute(string userSecretId)
26 | {
27 | if (string.IsNullOrEmpty(userSecretId))
28 | {
29 | throw new ArgumentException(Resources.Common_StringNullOrEmpty, nameof(userSecretId));
30 | }
31 |
32 | UserSecretsId = userSecretId;
33 | }
34 |
35 | ///
36 | /// The user secrets ID.
37 | ///
38 | public string UserSecretsId { get; }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/Config.UserSecrets/build/netstandard2.0/Microsoft.Extensions.Configuration.UserSecrets.props:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/src/Config.UserSecrets/build/netstandard2.0/Microsoft.Extensions.Configuration.UserSecrets.targets:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | $(MSBuildAllProjects);$(MSBuildThisFileFullPath)
5 | true
6 |
7 |
8 |
9 |
10 | <_Parameter1>$(UserSecretsId.Trim())
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/src/Config.Xml/Config.Xml.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Microsoft.Extensions.Configuration.Xml
5 | Microsoft.Extensions.Configuration.Xml
6 | XML configuration provider implementation for Microsoft.Extensions.Configuration.
7 | netstandard2.0
8 | $(PackageTags);xml
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/src/Config.Xml/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) .NET Foundation. All rights reserved.
2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3 |
4 | using System.Runtime.CompilerServices;
5 |
6 | [assembly: InternalsVisibleTo("Microsoft.Extensions.Configuration.Xml.Test, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
7 |
8 |
--------------------------------------------------------------------------------
/src/Config.Xml/Properties/Resources.Designer.cs:
--------------------------------------------------------------------------------
1 | //
2 | namespace Microsoft.Extensions.Configuration.Xml
3 | {
4 | using System.Globalization;
5 | using System.Reflection;
6 | using System.Resources;
7 |
8 | internal static class Resources
9 | {
10 | private static readonly ResourceManager _resourceManager
11 | = new ResourceManager("Microsoft.Extensions.Configuration.Xml.Resources", typeof(Resources).GetTypeInfo().Assembly);
12 |
13 | ///
14 | /// File path must be a non-empty string.
15 | ///
16 | internal static string Error_InvalidFilePath
17 | {
18 | get => GetString("Error_InvalidFilePath");
19 | }
20 |
21 | ///
22 | /// File path must be a non-empty string.
23 | ///
24 | internal static string FormatError_InvalidFilePath()
25 | => GetString("Error_InvalidFilePath");
26 |
27 | ///
28 | /// A duplicate key '{0}' was found.{1}
29 | ///
30 | internal static string Error_KeyIsDuplicated
31 | {
32 | get => GetString("Error_KeyIsDuplicated");
33 | }
34 |
35 | ///
36 | /// A duplicate key '{0}' was found.{1}
37 | ///
38 | internal static string FormatError_KeyIsDuplicated(object p0, object p1)
39 | => string.Format(CultureInfo.CurrentCulture, GetString("Error_KeyIsDuplicated"), p0, p1);
40 |
41 | ///
42 | /// XML namespaces are not supported.{0}
43 | ///
44 | internal static string Error_NamespaceIsNotSupported
45 | {
46 | get => GetString("Error_NamespaceIsNotSupported");
47 | }
48 |
49 | ///
50 | /// XML namespaces are not supported.{0}
51 | ///
52 | internal static string FormatError_NamespaceIsNotSupported(object p0)
53 | => string.Format(CultureInfo.CurrentCulture, GetString("Error_NamespaceIsNotSupported"), p0);
54 |
55 | ///
56 | /// Unsupported node type '{0}' was found.{1}
57 | ///
58 | internal static string Error_UnsupportedNodeType
59 | {
60 | get => GetString("Error_UnsupportedNodeType");
61 | }
62 |
63 | ///
64 | /// Unsupported node type '{0}' was found.{1}
65 | ///
66 | internal static string FormatError_UnsupportedNodeType(object p0, object p1)
67 | => string.Format(CultureInfo.CurrentCulture, GetString("Error_UnsupportedNodeType"), p0, p1);
68 |
69 | ///
70 | /// Line {0}, position {1}.
71 | ///
72 | internal static string Msg_LineInfo
73 | {
74 | get => GetString("Msg_LineInfo");
75 | }
76 |
77 | ///
78 | /// Line {0}, position {1}.
79 | ///
80 | internal static string FormatMsg_LineInfo(object p0, object p1)
81 | => string.Format(CultureInfo.CurrentCulture, GetString("Msg_LineInfo"), p0, p1);
82 |
83 | private static string GetString(string name, params string[] formatterNames)
84 | {
85 | var value = _resourceManager.GetString(name);
86 |
87 | System.Diagnostics.Debug.Assert(value != null);
88 |
89 | if (formatterNames != null)
90 | {
91 | for (var i = 0; i < formatterNames.Length; i++)
92 | {
93 | value = value.Replace("{" + formatterNames[i] + "}", "{" + i + "}");
94 | }
95 | }
96 |
97 | return value;
98 | }
99 | }
100 | }
101 |
--------------------------------------------------------------------------------
/src/Config.Xml/XmlConfigurationSource.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) .NET Foundation. All rights reserved.
2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3 |
4 | namespace Microsoft.Extensions.Configuration.Xml
5 | {
6 | ///
7 | /// An XML file based .
8 | ///
9 | public class XmlConfigurationSource : FileConfigurationSource
10 | {
11 | ///
12 | /// Builds the for this source.
13 | ///
14 | /// The .
15 | /// A
16 | public override IConfigurationProvider Build(IConfigurationBuilder builder)
17 | {
18 | EnsureDefaults(builder);
19 | return new XmlConfigurationProvider(this);
20 | }
21 | }
22 | }
--------------------------------------------------------------------------------
/src/Config.Xml/XmlDocumentDecryptor.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) .NET Foundation. All rights reserved.
2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3 |
4 | using System;
5 | using System.IO;
6 | using System.Security.Cryptography.Xml;
7 | using System.Xml;
8 |
9 | namespace Microsoft.Extensions.Configuration.Xml
10 | {
11 | ///
12 | /// Class responsible for encrypting and decrypting XML.
13 | ///
14 | public class XmlDocumentDecryptor
15 | {
16 | ///
17 | /// Accesses the singleton decryptor instance.
18 | ///
19 | public static readonly XmlDocumentDecryptor Instance = new XmlDocumentDecryptor();
20 |
21 | private readonly Func _encryptedXmlFactory;
22 |
23 | ///
24 | /// Initializes a XmlDocumentDecryptor.
25 | ///
26 | // don't create an instance of this directly
27 | protected XmlDocumentDecryptor()
28 | : this(DefaultEncryptedXmlFactory)
29 | {
30 | }
31 |
32 | // for testing only
33 | internal XmlDocumentDecryptor(Func encryptedXmlFactory)
34 | {
35 | _encryptedXmlFactory = encryptedXmlFactory;
36 | }
37 |
38 | private static bool ContainsEncryptedData(XmlDocument document)
39 | {
40 | // EncryptedXml will simply decrypt the document in-place without telling
41 | // us that it did so, so we need to perform a check to see if EncryptedXml
42 | // will actually do anything. The below check for an encrypted data blob
43 | // is the same one that EncryptedXml would have performed.
44 | var namespaceManager = new XmlNamespaceManager(document.NameTable);
45 | namespaceManager.AddNamespace("enc", "http://www.w3.org/2001/04/xmlenc#");
46 | return (document.SelectSingleNode("//enc:EncryptedData", namespaceManager) != null);
47 | }
48 |
49 | ///
50 | /// Returns an XmlReader that decrypts data transparently.
51 | ///
52 | public XmlReader CreateDecryptingXmlReader(Stream input, XmlReaderSettings settings)
53 | {
54 | // XML-based configurations aren't really all that big, so we can buffer
55 | // the whole thing in memory while we determine decryption operations.
56 | var memStream = new MemoryStream();
57 | input.CopyTo(memStream);
58 | memStream.Position = 0;
59 |
60 | // First, consume the entire XmlReader as an XmlDocument.
61 | var document = new XmlDocument();
62 | using (var reader = XmlReader.Create(memStream, settings))
63 | {
64 | document.Load(reader);
65 | }
66 | memStream.Position = 0;
67 |
68 | if (ContainsEncryptedData(document))
69 | {
70 | return DecryptDocumentAndCreateXmlReader(document);
71 | }
72 | else
73 | {
74 | // If no decryption would have taken place, return a new fresh reader
75 | // based on the memory stream (which doesn't need to be disposed).
76 | return XmlReader.Create(memStream, settings);
77 | }
78 | }
79 |
80 | ///
81 | /// Creates a reader that can decrypt an encrypted XML document.
82 | ///
83 | /// The document.
84 | /// An XmlReader which can read the document.
85 | protected virtual XmlReader DecryptDocumentAndCreateXmlReader(XmlDocument document)
86 | {
87 | // Perform the actual decryption step, updating the XmlDocument in-place.
88 | var encryptedXml = _encryptedXmlFactory(document);
89 | encryptedXml.DecryptDocument();
90 |
91 | // Finally, return the new XmlReader from the updated XmlDocument.
92 | // Error messages based on this XmlReader won't show line numbers,
93 | // but that's fine since we transformed the document anyway.
94 | return document.CreateNavigator().ReadSubtree();
95 | }
96 |
97 | private static EncryptedXml DefaultEncryptedXmlFactory(XmlDocument document)
98 | => new EncryptedXml(document);
99 | }
100 | }
101 |
--------------------------------------------------------------------------------
/src/Config/ChainedBuilderExtensions.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) .NET Foundation. All rights reserved.
2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3 |
4 | using System;
5 | using System.Collections.Generic;
6 |
7 | namespace Microsoft.Extensions.Configuration
8 | {
9 | ///
10 | /// IConfigurationBuilder extension methods for the chaind configuration provider.
11 | ///
12 | public static class ChainedBuilderExtensions
13 | {
14 | ///
15 | /// Adds an existing configuration to .
16 | ///
17 | /// The to add to.
18 | /// The to add.
19 | /// The .
20 | public static IConfigurationBuilder AddConfiguration(this IConfigurationBuilder configurationBuilder, IConfiguration config)
21 | {
22 | if (configurationBuilder == null)
23 | {
24 | throw new ArgumentNullException(nameof(configurationBuilder));
25 | }
26 | if (config == null)
27 | {
28 | throw new ArgumentNullException(nameof(config));
29 | }
30 |
31 | configurationBuilder.Add(new ChainedConfigurationSource { Configuration = config });
32 | return configurationBuilder;
33 | }
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/Config/ChainedConfigurationProvider.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) .NET Foundation. All rights reserved.
2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3 |
4 | using System;
5 | using System.Collections.Generic;
6 | using System.Linq;
7 | using Microsoft.Extensions.Primitives;
8 |
9 | namespace Microsoft.Extensions.Configuration
10 | {
11 | ///
12 | /// Chained implementation of
13 | ///
14 | public class ChainedConfigurationProvider : IConfigurationProvider
15 | {
16 | private readonly IConfiguration _config;
17 |
18 | ///
19 | /// Initialize a new instance from the source configuration.
20 | ///
21 | /// The source configuration.
22 | public ChainedConfigurationProvider(ChainedConfigurationSource source)
23 | {
24 | if (source == null)
25 | {
26 | throw new ArgumentNullException(nameof(source));
27 | }
28 | if (source.Configuration == null)
29 | {
30 | throw new ArgumentNullException(nameof(source.Configuration));
31 | }
32 |
33 | _config = source.Configuration;
34 | }
35 |
36 | ///
37 | /// Tries to get a configuration value for the specified key.
38 | ///
39 | /// The key.
40 | /// The value.
41 | /// True if a value for the specified key was found, otherwise false.
42 | public bool TryGet(string key, out string value)
43 | {
44 | value = _config[key];
45 | return !string.IsNullOrEmpty(value);
46 | }
47 |
48 | ///
49 | /// Sets a configuration value for the specified key.
50 | ///
51 | /// The key.
52 | /// The value.
53 | public void Set(string key, string value) => _config[key] = value;
54 |
55 | ///
56 | /// Returns a change token if this provider supports change tracking, null otherwise.
57 | ///
58 | ///
59 | public IChangeToken GetReloadToken() => _config.GetReloadToken();
60 |
61 | ///
62 | /// Loads configuration values from the source represented by this .
63 | ///
64 | public void Load() { }
65 |
66 | ///
67 | /// Returns the immediate descendant configuration keys for a given parent path based on this
68 | /// 's data and the set of keys returned by all the preceding
69 | /// s.
70 | ///
71 | /// The child keys returned by the preceding providers for the same parent path.
72 | /// The parent path.
73 | /// The child keys.
74 | public IEnumerable GetChildKeys(
75 | IEnumerable earlierKeys,
76 | string parentPath)
77 | {
78 | var section = parentPath == null ? _config : _config.GetSection(parentPath);
79 | var children = section.GetChildren();
80 | var keys = new List();
81 | keys.AddRange(children.Select(c => c.Key));
82 | return keys.Concat(earlierKeys)
83 | .OrderBy(k => k, ConfigurationKeyComparer.Instance);
84 | }
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/src/Config/ChainedConfigurationSource.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) .NET Foundation. All rights reserved.
2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3 |
4 | namespace Microsoft.Extensions.Configuration
5 | {
6 | ///
7 | /// Represents a chained IConfiguration as an .
8 | ///
9 | public class ChainedConfigurationSource : IConfigurationSource
10 | {
11 | ///
12 | /// The chained configuration.
13 | ///
14 | public IConfiguration Configuration { get; set; }
15 |
16 | ///
17 | /// Builds the for this source.
18 | ///
19 | /// The .
20 | /// A
21 | public IConfigurationProvider Build(IConfigurationBuilder builder)
22 | => new ChainedConfigurationProvider(this);
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/Config/Config.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Microsoft.Extensions.Configuration
5 | Microsoft.Extensions.Configuration
6 | Implementation of key-value pair based configuration for Microsoft.Extensions.Configuration. Includes the memory configuration provider.
7 | netstandard2.0
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/src/Config/ConfigurationBuilder.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) .NET Foundation. All rights reserved.
2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3 |
4 | using System;
5 | using System.Collections.Generic;
6 |
7 | namespace Microsoft.Extensions.Configuration
8 | {
9 | ///
10 | /// Used to build key/value based configuration settings for use in an application.
11 | ///
12 | public class ConfigurationBuilder : IConfigurationBuilder
13 | {
14 | ///
15 | /// Returns the sources used to obtain configuration values.
16 | ///
17 | public IList Sources { get; } = new List();
18 |
19 | ///
20 | /// Gets a key/value collection that can be used to share data between the
21 | /// and the registered s.
22 | ///
23 | public IDictionary Properties { get; } = new Dictionary();
24 |
25 | ///
26 | /// Adds a new configuration source.
27 | ///
28 | /// The configuration source to add.
29 | /// The same .
30 | public IConfigurationBuilder Add(IConfigurationSource source)
31 | {
32 | if (source == null)
33 | {
34 | throw new ArgumentNullException(nameof(source));
35 | }
36 |
37 | Sources.Add(source);
38 | return this;
39 | }
40 |
41 | ///
42 | /// Builds an with keys and values from the set of providers registered in
43 | /// .
44 | ///
45 | /// An with keys and values from the registered providers.
46 | public IConfigurationRoot Build()
47 | {
48 | var providers = new List();
49 | foreach (var source in Sources)
50 | {
51 | var provider = source.Build(this);
52 | providers.Add(provider);
53 | }
54 | return new ConfigurationRoot(providers);
55 | }
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/src/Config/ConfigurationKeyComparer.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) .NET Foundation. All rights reserved.
2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3 |
4 | using System;
5 | using System.Collections.Generic;
6 |
7 | namespace Microsoft.Extensions.Configuration
8 | {
9 | ///
10 | /// IComparer implementation used to order configuration keys.
11 | ///
12 | public class ConfigurationKeyComparer : IComparer
13 | {
14 | private static readonly string[] _keyDelimiterArray = new[] { ConfigurationPath.KeyDelimiter };
15 |
16 | ///
17 | /// The default instance.
18 | ///
19 | public static ConfigurationKeyComparer Instance { get; } = new ConfigurationKeyComparer();
20 |
21 | ///
22 | /// Compares two strings.
23 | ///
24 | /// First string.
25 | /// Second string.
26 | ///
27 | public int Compare(string x, string y)
28 | {
29 | var xParts = x?.Split(_keyDelimiterArray, StringSplitOptions.RemoveEmptyEntries) ?? new string[0];
30 | var yParts = y?.Split(_keyDelimiterArray, StringSplitOptions.RemoveEmptyEntries) ?? new string[0];
31 |
32 | // Compare each part until we get two parts that are not equal
33 | for (int i = 0; i < Math.Min(xParts.Length, yParts.Length); i++)
34 | {
35 | x = xParts[i];
36 | y = yParts[i];
37 |
38 | var value1 = 0;
39 | var value2 = 0;
40 |
41 | var xIsInt = x != null && int.TryParse(x, out value1);
42 | var yIsInt = y != null && int.TryParse(y, out value2);
43 |
44 | int result = 0;
45 |
46 | if (!xIsInt && !yIsInt)
47 | {
48 | // Both are strings
49 | result = string.Compare(x, y, StringComparison.OrdinalIgnoreCase);
50 | }
51 | else if (xIsInt && yIsInt)
52 | {
53 | // Both are int
54 | result = value1 - value2;
55 | }
56 | else
57 | {
58 | // Only one of them is int
59 | result = xIsInt ? -1 : 1;
60 | }
61 |
62 | if (result != 0)
63 | {
64 | // One of them is different
65 | return result;
66 | }
67 | }
68 |
69 | // If we get here, the common parts are equal.
70 | // If they are of the same length, then they are totally identical
71 | return xParts.Length - yParts.Length;
72 | }
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/src/Config/ConfigurationProvider.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) .NET Foundation. All rights reserved.
2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3 |
4 | using System;
5 | using System.Collections.Generic;
6 | using System.Linq;
7 | using System.Threading;
8 | using Microsoft.Extensions.Primitives;
9 |
10 | namespace Microsoft.Extensions.Configuration
11 | {
12 | ///
13 | /// Base helper class for implementing an
14 | ///
15 | public abstract class ConfigurationProvider : IConfigurationProvider
16 | {
17 | private ConfigurationReloadToken _reloadToken = new ConfigurationReloadToken();
18 |
19 | ///
20 | /// Initializes a new
21 | ///
22 | protected ConfigurationProvider()
23 | {
24 | Data = new Dictionary(StringComparer.OrdinalIgnoreCase);
25 | }
26 |
27 | ///
28 | /// The configuration key value pairs for this provider.
29 | ///
30 | protected IDictionary Data { get; set; }
31 |
32 | ///
33 | /// Attempts to find a value with the given key, returns true if one is found, false otherwise.
34 | ///
35 | /// The key to lookup.
36 | /// The value found at key if one is found.
37 | /// True if key has a value, false otherwise.
38 | public virtual bool TryGet(string key, out string value)
39 | => Data.TryGetValue(key, out value);
40 |
41 | ///
42 | /// Sets a value for a given key.
43 | ///
44 | /// The configuration key to set.
45 | /// The value to set.
46 | public virtual void Set(string key, string value)
47 | => Data[key] = value;
48 |
49 | ///
50 | /// Loads (or reloads) the data for this provider.
51 | ///
52 | public virtual void Load()
53 | { }
54 |
55 | ///
56 | /// Returns the list of keys that this provider has.
57 | ///
58 | /// The earlier keys that other providers contain.
59 | /// The path for the parent IConfiguration.
60 | /// The list of keys for this provider.
61 | public virtual IEnumerable GetChildKeys(
62 | IEnumerable earlierKeys,
63 | string parentPath)
64 | {
65 | var prefix = parentPath == null ? string.Empty : parentPath + ConfigurationPath.KeyDelimiter;
66 |
67 | return Data
68 | .Where(kv => kv.Key.StartsWith(prefix, StringComparison.OrdinalIgnoreCase))
69 | .Select(kv => Segment(kv.Key, prefix.Length))
70 | .Concat(earlierKeys)
71 | .OrderBy(k => k, ConfigurationKeyComparer.Instance);
72 | }
73 |
74 | private static string Segment(string key, int prefixLength)
75 | {
76 | var indexOf = key.IndexOf(ConfigurationPath.KeyDelimiter, prefixLength, StringComparison.OrdinalIgnoreCase);
77 | return indexOf < 0 ? key.Substring(prefixLength) : key.Substring(prefixLength, indexOf - prefixLength);
78 | }
79 |
80 | ///
81 | /// Returns a that can be used to listen when this provider is reloaded.
82 | ///
83 | ///
84 | public IChangeToken GetReloadToken()
85 | {
86 | return _reloadToken;
87 | }
88 |
89 | ///
90 | /// Triggers the reload change token and creates a new one.
91 | ///
92 | protected void OnReload()
93 | {
94 | var previousToken = Interlocked.Exchange(ref _reloadToken, new ConfigurationReloadToken());
95 | previousToken.OnReload();
96 | }
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/src/Config/ConfigurationReloadToken.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) .NET Foundation. All rights reserved.
2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3 |
4 | using System;
5 | using System.Threading;
6 | using Microsoft.Extensions.Primitives;
7 |
8 | namespace Microsoft.Extensions.Configuration
9 | {
10 | ///
11 | /// Implements
12 | ///
13 | public class ConfigurationReloadToken : IChangeToken
14 | {
15 | private CancellationTokenSource _cts = new CancellationTokenSource();
16 |
17 | ///
18 | /// Indicates if this token will proactively raise callbacks. Callbacks are still guaranteed to be invoked, eventually.
19 | ///
20 | public bool ActiveChangeCallbacks => true;
21 |
22 | ///
23 | /// Gets a value that indicates if a change has occurred.
24 | ///
25 | public bool HasChanged => _cts.IsCancellationRequested;
26 |
27 | ///
28 | /// Registers for a callback that will be invoked when the entry has changed.
29 | /// MUST be set before the callback is invoked.
30 | ///
31 | /// The callback to invoke.
32 | /// State to be passed into the callback.
33 | ///
34 | public IDisposable RegisterChangeCallback(Action