From 2ef7e9b7364d71d9ab8e0a44dafef991fbfecb01 Mon Sep 17 00:00:00 2001 From: zhenlei520 Date: Thu, 19 May 2022 16:23:59 +0800 Subject: [PATCH] fix(Configuration): Fixed the issue that the port specified in launchSettings.json did not take effect after using MasaConfiguration --- .../Internal/ConfigurationExtensions.cs | 25 +++++++ .../ServiceCollectionExtensions.cs | 72 +++++++++++++++++-- .../Masa.Contrib.Configuration/_Imports.cs | 5 ++ .../ConfigurationTest.cs | 34 ++++++++- 4 files changed, 127 insertions(+), 9 deletions(-) create mode 100644 src/Configuration/Masa.Contrib.Configuration/Internal/ConfigurationExtensions.cs diff --git a/src/Configuration/Masa.Contrib.Configuration/Internal/ConfigurationExtensions.cs b/src/Configuration/Masa.Contrib.Configuration/Internal/ConfigurationExtensions.cs new file mode 100644 index 000000000..0212effe6 --- /dev/null +++ b/src/Configuration/Masa.Contrib.Configuration/Internal/ConfigurationExtensions.cs @@ -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 DefaultExcludeConfigurationSourceTypes = new() + { + typeof(CommandLineConfigurationSource), + typeof(EnvironmentVariablesConfigurationSource), + typeof(KeyPerFileConfigurationSource), + typeof(MemoryConfigurationSource) + }; + + public static IConfigurationBuilder AddRange(this IConfigurationBuilder configurationBuilder, + IEnumerable configurationSources) + { + foreach (var configurationSource in configurationSources) + { + configurationBuilder.Add(configurationSource); + } + return configurationBuilder; + } +} diff --git a/src/Configuration/Masa.Contrib.Configuration/ServiceCollectionExtensions.cs b/src/Configuration/Masa.Contrib.Configuration/ServiceCollectionExtensions.cs index 6b86b7fe7..0c6ef3b0f 100644 --- a/src/Configuration/Masa.Contrib.Configuration/ServiceCollectionExtensions.cs +++ b/src/Configuration/Masa.Contrib.Configuration/ServiceCollectionExtensions.cs @@ -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 excludeConfigurationSourceTypes, + params Assembly[] assemblies) + => builder.AddMasaConfiguration(null, excludeConfigurationSourceTypes, assemblies); + + public static WebApplicationBuilder AddMasaConfiguration( + this WebApplicationBuilder builder, + Action? configureDelegate, + params Assembly[] assemblies) + => builder.AddMasaConfiguration( + configureDelegate, + Internal.ConfigurationExtensions.DefaultExcludeConfigurationSourceTypes, + assemblies); public static WebApplicationBuilder AddMasaConfiguration( this WebApplicationBuilder builder, Action? configureDelegate, + List 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; @@ -38,6 +59,20 @@ public static IConfigurationRoot CreateMasaConfiguration( Action? configureDelegate, IConfigurationBuilder configurationBuilder, params Assembly[] assemblies) + { + return services.CreateMasaConfiguration( + configureDelegate, + configurationBuilder, + Internal.ConfigurationExtensions.DefaultExcludeConfigurationSourceTypes, + assemblies); + } + + public static IConfigurationRoot CreateMasaConfiguration( + this IServiceCollection services, + Action? configureDelegate, + IConfigurationBuilder configurationBuilder, + List excludeConfigurationSourceTypes, + params Assembly[] assemblies) { if (services.Any(service => service.ImplementationType == typeof(MasaConfigurationProvider))) return new ConfigurationBuilder().Build(); @@ -46,17 +81,23 @@ public static IConfigurationRoot CreateMasaConfiguration( services.AddOptions(); services.TryAddSingleton(); - 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()); + var localConfigurationRepository = new LocalMasaConfigurationRepository( + masaConfigurationBuilder.Configuration, + services.BuildServiceProvider().GetService()); 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); @@ -80,6 +121,21 @@ public static IConfigurationRoot CreateMasaConfiguration( return configuration; } + private static IConfigurationBuilder GetMigrateConfigurationBuilder( + IConfigurationBuilder sourceConfigurationBuilder, + List 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(); @@ -112,7 +168,9 @@ internal static void ConfigureOption( services.TryAdd(new ServiceDescriptor(typeof(IOptionsChangeTokenSource<>).MakeGenericType(optionType), configurationChangeTokenSource)); - Action configureBinder = _ => { }; + Action configureBinder = _ => + { + }; var configureOptions = Activator.CreateInstance(typeof(NamedConfigureFromConfigurationOptions<>).MakeGenericType(optionType), string.Empty, diff --git a/src/Configuration/Masa.Contrib.Configuration/_Imports.cs b/src/Configuration/Masa.Contrib.Configuration/_Imports.cs index e4ac3a3b2..e346ef12f 100644 --- a/src/Configuration/Masa.Contrib.Configuration/_Imports.cs +++ b/src/Configuration/Masa.Contrib.Configuration/_Imports.cs @@ -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; diff --git a/test/Masa.Contrib.Configuration.Tests/ConfigurationTest.cs b/test/Masa.Contrib.Configuration.Tests/ConfigurationTest.cs index ac1114dbc..994c5c8c0 100644 --- a/test/Masa.Contrib.Configuration.Tests/ConfigurationTest.cs +++ b/test/Masa.Contrib.Configuration.Tests/ConfigurationTest.cs @@ -40,7 +40,7 @@ public void TestAddJsonFileShouldReturnRabbitMqOptionAndSystemOptionsExist() var serviceProvider = builder.Services.BuildServiceProvider(); var rabbitMqOptions = serviceProvider.GetRequiredService>(); 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>(); Assert.IsTrue(systemOptions is { Value.Name: "Masa TEST" }); @@ -74,7 +74,7 @@ public void TestManuallyMappingShouldReturnRedisExist() var serviceProvider = builder.Services.BuildServiceProvider(); var rabbitMqOptions = serviceProvider.GetRequiredService>(); 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>(); Assert.IsTrue(systemOptions is { Value.Name: "Masa TEST" }); @@ -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()); + }, new List(), 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()); + }, typeof(ConfigurationTest).Assembly); + + Assert.IsTrue(builder.Configuration["project-name"] == "masa-unit-test"); + } }