Allow ConfigureServices to be called multiple times.

This commit is contained in:
Chris R 2016-03-10 16:15:22 -08:00
parent b48b5f1553
commit a77e7cf6da
2 changed files with 49 additions and 7 deletions

View File

@ -2,6 +2,7 @@
// 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 System.Diagnostics;
using System.IO;
using System.Reflection;
@ -28,12 +29,11 @@ namespace Microsoft.AspNetCore.Hosting
{
private readonly IHostingEnvironment _hostingEnvironment;
private readonly ILoggerFactory _loggerFactory;
private readonly List<Action<IServiceCollection>> _configureServicesDelegates;
private IConfiguration _config = new ConfigurationBuilder().AddInMemoryCollection().Build();
private WebHostOptions _options;
private Action<IServiceCollection> _configureServices;
// Only one of these should be set
private StartupMethods _startup;
private Type _startupType;
@ -45,6 +45,7 @@ namespace Microsoft.AspNetCore.Hosting
{
_hostingEnvironment = new HostingEnvironment();
_loggerFactory = new LoggerFactory();
_configureServicesDelegates = new List<Action<IServiceCollection>>();
}
/// <summary>
@ -102,13 +103,19 @@ namespace Microsoft.AspNetCore.Hosting
}
/// <summary>
/// Specify the delegate that is used to configure the services of the web application.
/// Adds a delegate for configuring additional services for the host or web application. This may be called
/// multiple times.
/// </summary>
/// <param name="configureServices">The delegate that configures the <see cref="IServiceCollection"/>.</param>
/// <param name="configureServices">A delegate for configuring the <see cref="IServiceCollection"/>.</param>
/// <returns>The <see cref="IWebHostBuilder"/>.</returns>
public IWebHostBuilder ConfigureServices(Action<IServiceCollection> configureServices)
{
_configureServices = configureServices;
if (configureServices == null)
{
throw new ArgumentNullException(nameof(configureServices));
}
_configureServicesDelegates.Add(configureServices);
return this;
}
@ -213,9 +220,9 @@ namespace Microsoft.AspNetCore.Hosting
}
}
if (_configureServices != null)
foreach (var configureServices in _configureServicesDelegates)
{
_configureServices(services);
configureServices(services);
}
return services;

View File

@ -148,6 +148,31 @@ namespace Microsoft.AspNetCore.Hosting
Assert.Equal("A public method named 'ConfigureProduction' or 'Configure' could not be found in the 'Microsoft.AspNetCore.Hosting.Fakes.StartupBoom' type.", exception.Message);
}
[Fact]
public void ConfigureServices_CanBeCalledMultipleTimes()
{
var callCount = 0; // Verify ordering
var hostBuilder = new WebHostBuilder()
.UseServer(new TestServer())
.ConfigureServices(services =>
{
Assert.Equal(0, callCount++);
services.AddTransient<ServiceA>();
})
.ConfigureServices(services =>
{
Assert.Equal(1, callCount++);
services.AddTransient<ServiceB>();
})
.Configure(app => { });
var host = hostBuilder.Build();
Assert.Equal(2, callCount);
Assert.NotNull(host.Services.GetRequiredService<ServiceA>());
Assert.NotNull(host.Services.GetRequiredService<ServiceB>());
}
[Fact]
public void CodeBasedSettingsCodeBasedOverride()
{
@ -418,5 +443,15 @@ namespace Microsoft.AspNetCore.Hosting
};
}
}
private class ServiceA
{
}
private class ServiceB
{
}
}
}