diff --git a/MetaPackages.sln b/MetaPackages.sln index 1404087..8b5782b 100644 --- a/MetaPackages.sln +++ b/MetaPackages.sln @@ -1,6 +1,6 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 15 -VisualStudioVersion = 15.0.26412.1 +VisualStudioVersion = 15.0.26507.0 MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{ED834E68-51C3-4ADE-ACC8-6BA6D4207C09}" EndProject @@ -46,6 +46,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TrimDeps", "tools\TrimDeps\ EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DependencyInjectionApp", "test\TestSites\DependencyInjectionApp\DependencyInjectionApp.csproj", "{65FE2E38-4529-4C93-A7B0-CF12DD7A70C3}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.All.Tests", "test\Microsoft.AspNetCore.All.Tests\Microsoft.AspNetCore.All.Tests.csproj", "{914D3FAD-8B94-4353-B24F-B264F675481C}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -100,6 +102,10 @@ Global {65FE2E38-4529-4C93-A7B0-CF12DD7A70C3}.Debug|Any CPU.Build.0 = Debug|Any CPU {65FE2E38-4529-4C93-A7B0-CF12DD7A70C3}.Release|Any CPU.ActiveCfg = Release|Any CPU {65FE2E38-4529-4C93-A7B0-CF12DD7A70C3}.Release|Any CPU.Build.0 = Release|Any CPU + {914D3FAD-8B94-4353-B24F-B264F675481C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {914D3FAD-8B94-4353-B24F-B264F675481C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {914D3FAD-8B94-4353-B24F-B264F675481C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {914D3FAD-8B94-4353-B24F-B264F675481C}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -118,7 +124,7 @@ Global {AE4216BF-D471-471B-82F3-6B6D004F7D17} = {ED834E68-51C3-4ADE-ACC8-6BA6D4207C09} {302400A0-98BB-4C04-88D4-C32DC2D4B945} = {ED834E68-51C3-4ADE-ACC8-6BA6D4207C09} {67E4C92F-6D12-4C52-BB79-B8D11BFC6B82} = {ED834E68-51C3-4ADE-ACC8-6BA6D4207C09} - {302400A0-98BB-4C04-88D4-C32DC2D4B945} = {ED834E68-51C3-4ADE-ACC8-6BA6D4207C09} {65FE2E38-4529-4C93-A7B0-CF12DD7A70C3} = {EC22261D-0DE1-47DE-8F7C-072675D6F5B4} + {914D3FAD-8B94-4353-B24F-B264F675481C} = {9E49B5B9-9E72-42FB-B684-90CA1B1BCF9C} EndGlobalSection EndGlobal diff --git a/src/Microsoft.AspNetCore/AspNetCoreExtensions.cs b/src/Microsoft.AspNetCore/AspNetCoreExtensions.cs new file mode 100644 index 0000000..ce27042 --- /dev/null +++ b/src/Microsoft.AspNetCore/AspNetCoreExtensions.cs @@ -0,0 +1,32 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Collections.Generic; +using Microsoft.AspNetCore.Builder; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; +using Microsoft.Extensions.Options; +using Microsoft.Extensions.Options.Infrastructure; + +namespace Microsoft.AspNetCore +{ + /// + /// Exposes extension method for establishing configuration defaults. + /// + public static class AspNetCoreExtensions + { + /// + /// Allows features to do some default setup for their options, i.e. binding against the default configuration. + /// + /// The to modify. + /// The service collection. + public static IServiceCollection ConfigureAspNetCoreDefaults(this IServiceCollection services) + { + services.AddTransient(typeof(IConfigureOptions<>), typeof(ConfigureDefaults<>)); + services.AddTransient(typeof(IConfigureNamedOptions<>), typeof(ConfigureDefaults<>)); + return services; + } + } +} \ No newline at end of file diff --git a/src/Microsoft.AspNetCore/KestrelServerOptionsSetup.cs b/src/Microsoft.AspNetCore/KestrelServerOptionsSetup.cs index a76e7f6..8a66a60 100644 --- a/src/Microsoft.AspNetCore/KestrelServerOptionsSetup.cs +++ b/src/Microsoft.AspNetCore/KestrelServerOptionsSetup.cs @@ -9,11 +9,11 @@ using Microsoft.AspNetCore.Server.Kestrel.Core; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Logging; -using Microsoft.Extensions.Options; +using Microsoft.Extensions.Options.Infrastructure; namespace Microsoft.AspNetCore { - internal class KestrelServerOptionsSetup : IConfigureOptions + internal class KestrelServerOptionsSetup : ConfigureDefaultOptions { private readonly IHostingEnvironment _hostingEnvironment; private readonly IConfiguration _configurationRoot; @@ -29,7 +29,7 @@ public KestrelServerOptionsSetup( _loggerFactory = loggerFactory; } - public void Configure(KestrelServerOptions options) + public override void Configure(string name, KestrelServerOptions options) { BindConfiguration(options); } @@ -38,7 +38,7 @@ private void BindConfiguration(KestrelServerOptions options) { var certificateLoader = new CertificateLoader(_configurationRoot.GetSection("Certificates"), _loggerFactory, _hostingEnvironment.EnvironmentName); - foreach (var endPoint in _configurationRoot.GetSection("Kestrel:EndPoints").GetChildren()) + foreach (var endPoint in _configurationRoot.GetSection("Microsoft:AspNetCore:Hosting:Kestrel:EndPoints").GetChildren()) { BindEndPoint(options, endPoint, certificateLoader); } diff --git a/src/Microsoft.AspNetCore/WebHost.cs b/src/Microsoft.AspNetCore/WebHost.cs index 303dffa..99d7b59 100644 --- a/src/Microsoft.AspNetCore/WebHost.cs +++ b/src/Microsoft.AspNetCore/WebHost.cs @@ -12,7 +12,7 @@ using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; -using Microsoft.Extensions.Options; +using Microsoft.Extensions.Options.Infrastructure; namespace Microsoft.AspNetCore { @@ -188,7 +188,7 @@ public static IWebHostBuilder CreateDefaultBuilder(string[] args) }) .ConfigureServices(services => { - services.AddTransient, KestrelServerOptionsSetup>(); + services.AddTransient, KestrelServerOptionsSetup>(); }); return builder; diff --git a/test/Microsoft.AspNetCore.All.Tests/ConfigurationTests.cs b/test/Microsoft.AspNetCore.All.Tests/ConfigurationTests.cs new file mode 100644 index 0000000..f327bec --- /dev/null +++ b/test/Microsoft.AspNetCore.All.Tests/ConfigurationTests.cs @@ -0,0 +1,69 @@ +// Copyright (c) .NET Foundation. All rights reserved. See License.txt in the project root for license information. + +using System; +using System.Collections.Generic; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; +using Microsoft.Extensions.Options.Infrastructure; +using Xunit; + +namespace Microsoft.AspNetCore.Tests +{ + public class ConfigurationTests + { + private class TestOptions + { + public string Message { get; set; } + } + + private class ConfigureTestDefault : ConfigureDefaultOptions + { + public ConfigureTestDefault(IConfiguration config) : + base(options => config.GetSection("Test").Bind(options)) + { } + } + + [Fact] + public void ConfigureAspNetCoreDefaultsEnablesBindAgainstDefaultConfig() + { + var dic = new Dictionary + { + { "Test:Message", "yadayada"} + }; + var configurationBuilder = new ConfigurationBuilder(); + configurationBuilder.AddInMemoryCollection(dic); + var config = configurationBuilder.Build(); + var services = new ServiceCollection() + .AddSingleton(config) + .AddOptions() + .AddTransient, ConfigureTestDefault>() + .ConfigureAspNetCoreDefaults(); + var sp = services.BuildServiceProvider(); + + var options = sp.GetRequiredService>().Value; + Assert.Equal("yadayada", options.Message); + } + + [Fact] + public void DefaultConfigIgnoredWithoutConfigureAspNetCoreDefaults() + { + var dic = new Dictionary + { + { "Test:Message", "yadayada"} + }; + var configurationBuilder = new ConfigurationBuilder(); + configurationBuilder.AddInMemoryCollection(dic); + var config = configurationBuilder.Build(); + var services = new ServiceCollection() + .AddSingleton(config) + .AddOptions() + .AddTransient, ConfigureTestDefault>(); + var sp = services.BuildServiceProvider(); + + var options = sp.GetRequiredService>().Value; + Assert.Null(options.Message); + } + + } +} \ No newline at end of file diff --git a/test/Microsoft.AspNetCore.All.Tests/Microsoft.AspNetCore.All.Tests.csproj b/test/Microsoft.AspNetCore.All.Tests/Microsoft.AspNetCore.All.Tests.csproj new file mode 100644 index 0000000..5e36052 --- /dev/null +++ b/test/Microsoft.AspNetCore.All.Tests/Microsoft.AspNetCore.All.Tests.csproj @@ -0,0 +1,20 @@ + + + + + + netcoreapp2.0 + + + + + + + + + + + + + + diff --git a/test/Microsoft.AspNetCore.FunctionalTests/WebHostFunctionalTests.cs b/test/Microsoft.AspNetCore.FunctionalTests/WebHostFunctionalTests.cs index e7074a1..a797aa4 100644 --- a/test/Microsoft.AspNetCore.FunctionalTests/WebHostFunctionalTests.cs +++ b/test/Microsoft.AspNetCore.FunctionalTests/WebHostFunctionalTests.cs @@ -106,11 +106,17 @@ public async Task BindsKestrelHttpEndPointFromConfiguration(string endPointAddre { File.WriteAllText("appsettings.json", @" { - ""Kestrel"": { - ""EndPoints"": { - ""EndPoint"": { - ""Address"": """ + endPointAddress + @""", - ""Port"": 0 + ""Microsoft"": { + ""AspNetCore"": { + ""Hosting"": { + ""Kestrel"": { + ""EndPoints"": { + ""EndPoint"": { + ""Address"": """ + endPointAddress + @""", + ""Port"": 0 + } + } + } } } } @@ -142,12 +148,18 @@ public async Task BindsKestrelHttpsEndPointFromConfiguration_ReferencedCertifica { File.WriteAllText("appsettings.json", @" { - ""Kestrel"": { - ""EndPoints"": { - ""EndPoint"": { - ""Address"": ""127.0.0.1"", - ""Port"": 0, - ""Certificate"": ""TestCert"" + ""Microsoft"": { + ""AspNetCore"": { + ""Hosting"": { + ""Kestrel"": { + ""EndPoints"": { + ""EndPoint"": { + ""Address"": ""127.0.0.1"", + ""Port"": 0, + ""Certificate"": ""TestCert"" + } + } + } } } }, @@ -181,15 +193,21 @@ public async Task BindsKestrelHttpsEndPointFromConfiguration_InlineCertificateFi { File.WriteAllText("appsettings.json", @" { - ""Kestrel"": { - ""EndPoints"": { - ""EndPoint"": { - ""Address"": ""127.0.0.1"", - ""Port"": 0, - ""Certificate"": { - ""Source"": ""File"", - ""Path"": ""testCert.pfx"", - ""Password"": ""testPassword"" + ""Microsoft"": { + ""AspNetCore"": { + ""Hosting"": { + ""Kestrel"": { + ""EndPoints"": { + ""EndPoint"": { + ""Address"": ""127.0.0.1"", + ""Port"": 0, + ""Certificate"": { + ""Source"": ""File"", + ""Path"": ""testCert.pfx"", + ""Password"": ""testPassword"" + } + } + } } } }