Browse Source

Implement IHostApplicationBuilder on WebApplicationBuilder (#48775)

https://github.com/dotnet/runtime/pull/86974 added support for a common interface between HostApplicationBuilder and WebApplicationBuilder. This implements the new interface on WebApplicationBuilder.
Eric Erhardt 2 years ago
parent
commit
1ac7ae5222

+ 10 - 1
src/DefaultBuilder/src/WebApplicationBuilder.cs

@@ -16,7 +16,7 @@ namespace Microsoft.AspNetCore.Builder;
 /// <summary>
 /// A builder for web applications and services.
 /// </summary>
-public sealed class WebApplicationBuilder
+public sealed class WebApplicationBuilder : IHostApplicationBuilder
 {
     private const string EndpointRouteBuilderKey = "__EndpointRouteBuilder";
     private const string AuthenticationMiddlewareSetKey = "__AuthenticationMiddlewareSet";
@@ -300,6 +300,12 @@ public sealed class WebApplicationBuilder
     /// </summary>
     public ConfigureHostBuilder Host { get; }
 
+    IDictionary<object, object> IHostApplicationBuilder.Properties => ((IHostApplicationBuilder)_hostApplicationBuilder).Properties;
+
+    IConfigurationManager IHostApplicationBuilder.Configuration => Configuration;
+
+    IHostEnvironment IHostApplicationBuilder.Environment => Environment;
+
     /// <summary>
     /// Builds the <see cref="WebApplication"/>.
     /// </summary>
@@ -407,4 +413,7 @@ public sealed class WebApplicationBuilder
             app.Properties[EndpointRouteBuilderKey] = priorRouteBuilder;
         }
     }
+
+    void IHostApplicationBuilder.ConfigureContainer<TContainerBuilder>(IServiceProviderFactory<TContainerBuilder> factory, Action<TContainerBuilder>? configure) =>
+        _hostApplicationBuilder.ConfigureContainer(factory, configure);
 }

+ 44 - 0
src/DefaultBuilder/test/Microsoft.AspNetCore.Tests/WebApplicationTests.cs

@@ -2368,6 +2368,29 @@ public class WebApplicationTests
         Assert.True(app.Properties.ContainsKey("__AuthorizationMiddlewareSet"));
     }
 
+    [Theory]
+    [MemberData(nameof(CreateBuilderFuncs))]
+    public void ImplementsIHostApplicationBuilderCorrectly(CreateBuilderFunc createBuilder)
+    {
+        var builder = createBuilder();
+        var iHostApplicationBuilder = (IHostApplicationBuilder)builder;
+
+        builder.Host.Properties["MyProp"] = 1;
+        Assert.Equal(1, iHostApplicationBuilder.Properties["MyProp"]);
+
+        Assert.Same(builder.Host.Properties, iHostApplicationBuilder.Properties);
+        Assert.Same(builder.Configuration, iHostApplicationBuilder.Configuration);
+        Assert.Same(builder.Logging, iHostApplicationBuilder.Logging);
+        Assert.Same(builder.Services, iHostApplicationBuilder.Services);
+        Assert.True(iHostApplicationBuilder.Environment.IsProduction());
+        Assert.NotNull(iHostApplicationBuilder.Environment.ContentRootFileProvider);
+
+        iHostApplicationBuilder.ConfigureContainer(new MyServiceProviderFactory());
+
+        var app = builder.Build();
+        Assert.IsType<MyServiceProvider>(app.Services);
+    }
+
     [Fact]
     public async Task UsingCreateBuilderResultsInRegexConstraintBeingPresent()
     {
@@ -2829,4 +2852,25 @@ public class WebApplicationTests
             };
         }
     }
+
+    private class MyServiceProviderFactory : IServiceProviderFactory<MyServiceProvider>
+    {
+        public MyServiceProvider CreateBuilder(IServiceCollection services) => new MyServiceProvider(services);
+
+        public IServiceProvider CreateServiceProvider(MyServiceProvider containerBuilder)
+        {
+            containerBuilder.Build();
+            return containerBuilder;
+        }
+    }
+
+    private class MyServiceProvider : IServiceProvider
+    {
+        private IServiceProvider _inner;
+        private IServiceCollection _services;
+
+        public MyServiceProvider(IServiceCollection services) => _services = services;
+        public void Build() => _inner = _services.BuildServiceProvider();
+        public object GetService(Type serviceType) => _inner.GetService(serviceType);
+    }
 }