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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Copyright (c) MASA Stack All rights reserved.
// Licensed under the MIT License. See LICENSE.txt in the project root for license information.

namespace Masa.Contrib.Configuration.Internal;

internal static class ConfigurationExtensions
{
public static readonly List<Type> DefaultExcludeConfigurationSourceTypes = new()
{
typeof(CommandLineConfigurationSource),
typeof(EnvironmentVariablesConfigurationSource),
typeof(KeyPerFileConfigurationSource),
typeof(MemoryConfigurationSource)
};

public static IConfigurationBuilder AddRange(this IConfigurationBuilder configurationBuilder,
IEnumerable<IConfigurationSource> configurationSources)
{
foreach (var configurationSource in configurationSources)
{
configurationBuilder.Add(configurationSource);
}
return configurationBuilder;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,41 @@ public static WebApplicationBuilder AddMasaConfiguration(
public static WebApplicationBuilder AddMasaConfiguration(
this WebApplicationBuilder builder,
params Assembly[] assemblies)
=> builder.AddMasaConfiguration(null, assemblies);
=> builder.AddMasaConfiguration(null, Internal.ConfigurationExtensions.DefaultExcludeConfigurationSourceTypes, assemblies);

public static WebApplicationBuilder AddMasaConfiguration(
this WebApplicationBuilder builder,
List<Type> excludeConfigurationSourceTypes,
params Assembly[] assemblies)
=> builder.AddMasaConfiguration(null, excludeConfigurationSourceTypes, assemblies);

public static WebApplicationBuilder AddMasaConfiguration(
this WebApplicationBuilder builder,
Action<IMasaConfigurationBuilder>? configureDelegate,
params Assembly[] assemblies)
=> builder.AddMasaConfiguration(
configureDelegate,
Internal.ConfigurationExtensions.DefaultExcludeConfigurationSourceTypes,
assemblies);

public static WebApplicationBuilder AddMasaConfiguration(
this WebApplicationBuilder builder,
Action<IMasaConfigurationBuilder>? configureDelegate,
List<Type> excludeConfigurationSourceTypes,
params Assembly[] assemblies)
{
ArgumentNullException.ThrowIfNull(excludeConfigurationSourceTypes, nameof(excludeConfigurationSourceTypes));

var configurationBuilder = GetConfigurationBuilder(builder.Configuration);

IConfigurationRoot masaConfiguration = builder.Services.CreateMasaConfiguration(configureDelegate, configurationBuilder, assemblies);
IConfigurationRoot masaConfiguration =
builder.Services.CreateMasaConfiguration(configureDelegate, configurationBuilder, excludeConfigurationSourceTypes, assemblies);
if (!masaConfiguration.Providers.Any())
return builder;

Microsoft.Extensions.Hosting.HostingHostBuilderExtensions.ConfigureAppConfiguration(builder.Host, configBuilder => configBuilder.Sources.Clear());
Microsoft.Extensions.Hosting.HostingHostBuilderExtensions.ConfigureAppConfiguration(
builder.Host,
configBuilder => configBuilder.Sources.Clear());
builder.Configuration.AddConfiguration(masaConfiguration);

return builder;
Expand All @@ -38,6 +59,20 @@ public static IConfigurationRoot CreateMasaConfiguration(
Action<IMasaConfigurationBuilder>? configureDelegate,
IConfigurationBuilder configurationBuilder,
params Assembly[] assemblies)
{
return services.CreateMasaConfiguration(
configureDelegate,
configurationBuilder,
Internal.ConfigurationExtensions.DefaultExcludeConfigurationSourceTypes,
assemblies);
}

public static IConfigurationRoot CreateMasaConfiguration(
this IServiceCollection services,
Action<IMasaConfigurationBuilder>? configureDelegate,
IConfigurationBuilder configurationBuilder,
List<Type> excludeConfigurationSourceTypes,
params Assembly[] assemblies)
{
if (services.Any(service => service.ImplementationType == typeof(MasaConfigurationProvider)))
return new ConfigurationBuilder().Build();
Expand All @@ -46,17 +81,23 @@ public static IConfigurationRoot CreateMasaConfiguration(
services.AddOptions();
services.TryAddSingleton<IMasaConfiguration, DefaultMasaConfiguration>();

MasaConfigurationBuilder masaConfigurationBuilder = new MasaConfigurationBuilder(services, configurationBuilder);
MasaConfigurationBuilder masaConfigurationBuilder = new MasaConfigurationBuilder(services,
GetMigrateConfigurationBuilder(configurationBuilder, excludeConfigurationSourceTypes));
configureDelegate?.Invoke(masaConfigurationBuilder);

MasaConfigurationBuilder builder = new(services, new ConfigurationBuilder());
builder.AddRelations(masaConfigurationBuilder.Relations.ToArray());
masaConfigurationBuilder.Repositories.ForEach(repository => builder.AddRepository(repository));
var localConfigurationRepository = new LocalMasaConfigurationRepository(masaConfigurationBuilder.Configuration, services.BuildServiceProvider().GetService<ILoggerFactory>());
var localConfigurationRepository = new LocalMasaConfigurationRepository(
masaConfigurationBuilder.Configuration,
services.BuildServiceProvider().GetService<ILoggerFactory>());
builder.AddRepository(localConfigurationRepository);

var source = new MasaConfigurationSource(builder);
var configuration = builder.Add(source).Build();
var configuration = builder
.Add(source)
.AddRange(configurationBuilder.Sources.Where(s => excludeConfigurationSourceTypes.Contains(s.GetType())))
.Build();

builder.AutoMapping(assemblies);

Expand All @@ -80,6 +121,21 @@ public static IConfigurationRoot CreateMasaConfiguration(
return configuration;
}

private static IConfigurationBuilder GetMigrateConfigurationBuilder(
IConfigurationBuilder sourceConfigurationBuilder,
List<Type> configurationSourceTypes)
{
var configurationBuilder = new ConfigurationBuilder();
foreach (var configurationSource in sourceConfigurationBuilder.Sources)
{
if (!configurationSourceTypes.Contains(configurationSource.GetType()))
{
configurationBuilder.Add(configurationSource);
}
}
return configurationBuilder;
}

private static IConfigurationBuilder GetConfigurationBuilder(ConfigurationManager configuration)
{
var configurationBuilder = new ConfigurationBuilder();
Expand Down Expand Up @@ -112,7 +168,9 @@ internal static void ConfigureOption(
services.TryAdd(new ServiceDescriptor(typeof(IOptionsChangeTokenSource<>).MakeGenericType(optionType),
configurationChangeTokenSource));

Action<BinderOptions> configureBinder = _ => { };
Action<BinderOptions> configureBinder = _ =>
{
};
var configureOptions =
Activator.CreateInstance(typeof(NamedConfigureFromConfigurationOptions<>).MakeGenericType(optionType),
string.Empty,
Expand Down
5 changes: 5 additions & 0 deletions src/Configuration/Masa.Contrib.Configuration/_Imports.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,13 @@

global using Masa.BuildingBlocks.Configuration;
global using Masa.BuildingBlocks.Configuration.Options;
global using Masa.Contrib.Configuration.Internal;
global using Microsoft.AspNetCore.Builder;
global using Microsoft.Extensions.Configuration;
global using Microsoft.Extensions.Configuration.CommandLine;
global using Microsoft.Extensions.Configuration.EnvironmentVariables;
global using Microsoft.Extensions.Configuration.KeyPerFile;
global using Microsoft.Extensions.Configuration.Memory;
global using Microsoft.Extensions.DependencyInjection;
global using Microsoft.Extensions.DependencyInjection.Extensions;
global using Microsoft.Extensions.Logging;
Expand Down
34 changes: 32 additions & 2 deletions test/Masa.Contrib.Configuration.Tests/ConfigurationTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public void TestAddJsonFileShouldReturnRabbitMqOptionAndSystemOptionsExist()
var serviceProvider = builder.Services.BuildServiceProvider();
var rabbitMqOptions = serviceProvider.GetRequiredService<IOptions<RabbitMqOptions>>();
Assert.IsTrue(rabbitMqOptions is
{ Value.HostName: "localhost", Value.UserName: "admin", Value.Password: "admin", Value.VirtualHost: "/", Value.Port: "5672" });
{ Value.HostName: "localhost", Value.UserName: "admin", Value.Password: "admin", Value.VirtualHost: "/", Value.Port: "5672" });

var systemOptions = serviceProvider.GetRequiredService<IOptions<SystemOptions>>();
Assert.IsTrue(systemOptions is { Value.Name: "Masa TEST" });
Expand Down Expand Up @@ -74,7 +74,7 @@ public void TestManuallyMappingShouldReturnRedisExist()
var serviceProvider = builder.Services.BuildServiceProvider();
var rabbitMqOptions = serviceProvider.GetRequiredService<IOptions<RabbitMqOptions>>();
Assert.IsTrue(rabbitMqOptions is
{ Value.HostName: "localhost", Value.UserName: "admin", Value.Password: "admin", Value.VirtualHost: "/", Value.Port: "5672" });
{ Value.HostName: "localhost", Value.UserName: "admin", Value.Password: "admin", Value.VirtualHost: "/", Value.Port: "5672" });

var systemOptions = serviceProvider.GetRequiredService<IOptions<SystemOptions>>();
Assert.IsTrue(systemOptions is { Value.Name: "Masa TEST" });
Expand Down Expand Up @@ -248,4 +248,34 @@ await File.WriteAllTextAsync(Path.Combine(rootPath, "customAppConfig.json"),

await File.WriteAllTextAsync(Path.Combine(rootPath, "customAppConfig.json"), oldContent);
}

[TestMethod]
public void TestEnvironmentConfigurationMigrated()
{
var builder = WebApplication.CreateBuilder();
Environment.SetEnvironmentVariable("project-name", "masa-unit-test");
builder.AddMasaConfiguration(configurationBuilder =>
{
configurationBuilder.AddJsonFile("customAppConfig.json", true, true)
.AddJsonFile("rabbitMq.json", true, true);
configurationBuilder.UseMasaOptions(option => option.MappingLocal<RedisOptions>());
}, new List<Type>(), typeof(ConfigurationTest).Assembly);

Assert.IsTrue(builder.Configuration[$"{SectionTypes.Local}{ConfigurationPath.KeyDelimiter}project-name"] == "masa-unit-test");
}

[TestMethod]
public void TestEnvironmentConfigurationNotMigrated()
{
var builder = WebApplication.CreateBuilder();
Environment.SetEnvironmentVariable("project-name", "masa-unit-test");
builder.AddMasaConfiguration(configurationBuilder =>
{
configurationBuilder.AddJsonFile("customAppConfig.json", true, true)
.AddJsonFile("rabbitMq.json", true, true);
configurationBuilder.UseMasaOptions(option => option.MappingLocal<RedisOptions>());
}, typeof(ConfigurationTest).Assembly);

Assert.IsTrue(builder.Configuration["project-name"] == "masa-unit-test");
}
}