From d57d729d13c73750027944dda25082693d6b6d7f Mon Sep 17 00:00:00 2001 From: David Fowler Date: Tue, 14 Feb 2017 21:25:43 -0800 Subject: [PATCH] Enable configuring the default service provider (#943) * Enable configuring the default service provider - Added UseDefaultServiceProvider method - Made DelegateStartup use the IServiceProviderFactory. One downside here is that we can't use 3rd party DI containers with the Configure delegate since it's hardcoded to the the specific Startup type but that's not a regression. --- .../Startup/DelegateStartup.cs | 7 ++-- .../WebHostBuilderExtensions.cs | 22 +++++++++++- .../WebHostBuilderTests.cs | 35 +++++++++++++++++++ 3 files changed, 60 insertions(+), 4 deletions(-) diff --git a/src/Microsoft.AspNetCore.Hosting/Startup/DelegateStartup.cs b/src/Microsoft.AspNetCore.Hosting/Startup/DelegateStartup.cs index 843a8f6c6f..d354ad946e 100644 --- a/src/Microsoft.AspNetCore.Hosting/Startup/DelegateStartup.cs +++ b/src/Microsoft.AspNetCore.Hosting/Startup/DelegateStartup.cs @@ -3,14 +3,15 @@ using System; using Microsoft.AspNetCore.Builder; +using Microsoft.Extensions.DependencyInjection; namespace Microsoft.AspNetCore.Hosting { - public class DelegateStartup : StartupBase + public class DelegateStartup : StartupBase { private Action _configureApp; - - public DelegateStartup(Action configureApp) + + public DelegateStartup(IServiceProviderFactory factory, Action configureApp) : base(factory) { _configureApp = configureApp; } diff --git a/src/Microsoft.AspNetCore.Hosting/WebHostBuilderExtensions.cs b/src/Microsoft.AspNetCore.Hosting/WebHostBuilderExtensions.cs index 79598203f0..6e2b7a7552 100644 --- a/src/Microsoft.AspNetCore.Hosting/WebHostBuilderExtensions.cs +++ b/src/Microsoft.AspNetCore.Hosting/WebHostBuilderExtensions.cs @@ -6,6 +6,7 @@ using System.Reflection; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting.Internal; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; namespace Microsoft.AspNetCore.Hosting { @@ -29,7 +30,10 @@ namespace Microsoft.AspNetCore.Hosting return hostBuilder.UseSetting(WebHostDefaults.ApplicationKey, startupAssemblyName) .ConfigureServices(services => { - services.AddSingleton(new DelegateStartup(configureApp)); + services.AddSingleton(sp => + { + return new DelegateStartup(sp.GetRequiredService>(), configureApp); + }); }); } @@ -72,5 +76,21 @@ namespace Microsoft.AspNetCore.Hosting { return hostBuilder.UseStartup(typeof(TStartup)); } + + /// + /// Configures the default service provider + /// + /// The to configure. + /// A callback used to configure the for the default . + /// The . + public static IWebHostBuilder UseDefaultServiceProvider(this IWebHostBuilder hostBuilder, Action configure) + { + return hostBuilder.ConfigureServices(services => + { + var options = new ServiceProviderOptions(); + configure(options); + services.Replace(ServiceDescriptor.Singleton>(new DefaultServiceProviderFactory(options))); + }); + } } } \ No newline at end of file diff --git a/test/Microsoft.AspNetCore.Hosting.Tests/WebHostBuilderTests.cs b/test/Microsoft.AspNetCore.Hosting.Tests/WebHostBuilderTests.cs index 4d9795b45f..1f382dee5c 100644 --- a/test/Microsoft.AspNetCore.Hosting.Tests/WebHostBuilderTests.cs +++ b/test/Microsoft.AspNetCore.Hosting.Tests/WebHostBuilderTests.cs @@ -157,6 +157,28 @@ namespace Microsoft.AspNetCore.Hosting Assert.NotNull(host.Services.GetService()); } + [Fact] + public void ConfigureDefaultServiceProvider() + { + var hostBuilder = new WebHostBuilder() + .UseServer(new TestServer()) + .ConfigureServices(s => + { + s.AddTransient(); + s.AddScoped(); + }) + .Configure(app => + { + app.ApplicationServices.GetRequiredService(); + }) + .UseDefaultServiceProvider(options => + { + options.ValidateScopes = true; + }); + + Assert.Throws(() => hostBuilder.Build()); + } + [Fact] public void UseLoggerFactoryHonored() { @@ -621,6 +643,19 @@ namespace Microsoft.AspNetCore.Hosting } } + private class ServiceC + { + public ServiceC(ServiceD serviceD) + { + + } + } + + private class ServiceD + { + + } + private class ServiceA {