Microsoft.Extensions.Configuration.Binder by Microsoft
Nuget / site data
Details
Info
info
Name: Microsoft.Extensions.Configuration.Binder
Functionality to bind an object to data in configuration providers.
Author: Microsoft
NuGet: https://www.nuget.org/packages/Microsoft.Extensions.Configuration.Binder/
You can find more details at https://github.com/dotnet/runtime
Original Readme
note
About
note
Generating Binding for configuration files
How to use
Example ( source csproj, source files )
- CSharp Project
- Program.cs
- MyAppOptions.cs
This is the CSharp Project that references Microsoft.Extensions.Configuration.Binder
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<InvariantGlobalization>true</InvariantGlobalization>
</PropertyGroup>
<ItemGroup>
<!--<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="8.0.0" />-->
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="8.0.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.4.0" />
</ItemGroup>
<PropertyGroup>
<EnableConfigurationBindingGenerator>true</EnableConfigurationBindingGenerator>
</PropertyGroup>
<PropertyGroup>
<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
<CompilerGeneratedFilesOutputPath>$(BaseIntermediateOutputPath)\GX</CompilerGeneratedFilesOutputPath>
</PropertyGroup>
</Project>
This is the use of Microsoft.Extensions.Configuration.Binder in Program.cs
using ConfigBinderDemo;
using Microsoft.Extensions.Options;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
builder.Services.AddOptions<MyAppOptions>()
.BindConfiguration(MyAppOptions.ConfigName);
app.MapGet("/nameApp", (IOptions<MyAppOptions> opt) =>
{
try
{
var val = opt.Value.AppDisplayName;
return val;
}
catch (OptionsValidationException ex)
{
var problems = ex.Failures.ToArray();
return string.Join(",", problems);
}
})
.WithName("GetWeatherForecast")
.WithOpenApi();
app.Run();
internal record WeatherForecast(DateOnly Date, int TemperatureC, string? Summary)
{
public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
}
This is the use of Microsoft.Extensions.Configuration.Binder in MyAppOptions.cs
using System.Diagnostics;
namespace ConfigBinderDemo;
[DebuggerDisplay("{AppDisplayName}")]
public class MyAppOptions
{
public const string ConfigName = "MyAppOptionsInConfig";
public string AppDisplayName { get; set; } = string.Empty;
}
Generated Files
Those are taken from $(BaseIntermediateOutputPath)\GX
- BindingExtensions.g.cs
// <auto-generated/>
#nullable enable annotations
#nullable disable warnings
// Suppress warnings about [Obsolete] member usage in generated code.
#pragma warning disable CS0612, CS0618
namespace System.Runtime.CompilerServices
{
using System;
using System.CodeDom.Compiler;
[GeneratedCode("Microsoft.Extensions.Configuration.Binder.SourceGeneration", "8.0.10.6711")]
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
file sealed class InterceptsLocationAttribute : Attribute
{
public InterceptsLocationAttribute(string filePath, int line, int column)
{
}
}
}
namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
{
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using System;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.Globalization;
using System.Runtime.CompilerServices;
[GeneratedCode("Microsoft.Extensions.Configuration.Binder.SourceGeneration", "8.0.10.6711")]
file static class BindingExtensions
{
#region OptionsBuilder<TOptions> extensions.
/// <summary>Registers the dependency injection container to bind <typeparamref name="TOptions"/> against the <see cref="IConfiguration"/> obtained from the DI service provider.</summary>
[InterceptsLocation(@"D:\gth\RSCG_Examples\v2\rscg_examples\ConfigBinder\src\ConfigBinderDemo\Program.cs", 20, 14)]
public static OptionsBuilder<TOptions> BindConfiguration<TOptions>(this OptionsBuilder<TOptions> optionsBuilder, string configSectionPath, Action<BinderOptions>? configureBinder = null) where TOptions : class
{
if (optionsBuilder is null)
{
throw new ArgumentNullException(nameof(optionsBuilder));
}
if (configSectionPath is null)
{
throw new ArgumentNullException(nameof(configSectionPath));
}
optionsBuilder.Configure<IConfiguration>((instance, config) =>
{
if (config is null)
{
throw new ArgumentNullException(nameof(config));
}
IConfiguration section = string.Equals(string.Empty, configSectionPath, StringComparison.OrdinalIgnoreCase) ? config : config.GetSection(configSectionPath);
BindCoreMain(section, instance, typeof(TOptions), configureBinder);
});
optionsBuilder.Services.AddSingleton<IOptionsChangeTokenSource<TOptions>, ConfigurationChangeTokenSource<TOptions>>();
return optionsBuilder;
}
#endregion OptionsBuilder<TOptions> extensions.
#region Core binding extensions.
private readonly static Lazy<HashSet<string>> s_configKeys_MyAppOptions = new(() => new HashSet<string>(StringComparer.OrdinalIgnoreCase) { "AppDisplayName" });
public static void BindCoreMain(IConfiguration configuration, object instance, Type type, Action<BinderOptions>? configureOptions)
{
if (instance is null)
{
return;
}
if (!HasValueOrChildren(configuration))
{
return;
}
BinderOptions? binderOptions = GetBinderOptions(configureOptions);
if (type == typeof(global::ConfigBinderDemo.MyAppOptions))
{
var temp = (global::ConfigBinderDemo.MyAppOptions)instance;
BindCore(configuration, ref temp, defaultValueIfNotFound: false, binderOptions);
return;
}
throw new NotSupportedException($"Unable to bind to type '{type}': generator did not detect the type as input.");
}
public static void BindCore(IConfiguration configuration, ref global::ConfigBinderDemo.MyAppOptions instance, bool defaultValueIfNotFound, BinderOptions? binderOptions)
{
ValidateConfigurationKeys(typeof(global::ConfigBinderDemo.MyAppOptions), s_configKeys_MyAppOptions, configuration, binderOptions);
if (configuration["AppDisplayName"] is string value1)
{
instance.AppDisplayName = value1;
}
}
/// <summary>If required by the binder options, validates that there are no unknown keys in the input configuration object.</summary>
public static void ValidateConfigurationKeys(Type type, Lazy<HashSet<string>> keys, IConfiguration configuration, BinderOptions? binderOptions)
{
if (binderOptions?.ErrorOnUnknownConfiguration is true)
{
List<string>? temp = null;
foreach (IConfigurationSection section in configuration.GetChildren())
{
if (!keys.Value.Contains(section.Key))
{
(temp ??= new List<string>()).Add($"'{section.Key}'");
}
}
if (temp is not null)
{
throw new InvalidOperationException($"'ErrorOnUnknownConfiguration' was set on the provided BinderOptions, but the following properties were not found on the instance of {type}: {string.Join(", ", temp)}");
}
}
}
public static bool HasValueOrChildren(IConfiguration configuration)
{
if ((configuration as IConfigurationSection)?.Value is not null)
{
return true;
}
return AsConfigWithChildren(configuration) is not null;
}
public static IConfiguration? AsConfigWithChildren(IConfiguration configuration)
{
foreach (IConfigurationSection _ in configuration.GetChildren())
{
return configuration;
}
return null;
}
public static BinderOptions? GetBinderOptions(Action<BinderOptions>? configureOptions)
{
if (configureOptions is null)
{
return null;
}
BinderOptions binderOptions = new();
configureOptions(binderOptions);
if (binderOptions.BindNonPublicProperties)
{
throw new NotSupportedException($"The configuration binding source generator does not support 'BinderOptions.BindNonPublicProperties'.");
}
return binderOptions;
}
#endregion Core binding extensions.
}
}
Usefull
Download Example (.NET C# )
Share Microsoft.Extensions.Configuration.Binder
https://ignatandrei.github.io/RSCG_Examples/v2/docs/Microsoft.Extensions.Configuration.Binder