Support IServiceProvider ConfigureServices()

This commit is contained in:
Hao Kung 2014-10-16 11:44:52 -07:00
parent 33dd087e0f
commit 4efa6a428b
3 changed files with 96 additions and 13 deletions

View File

@ -43,17 +43,19 @@ namespace Microsoft.AspNet.Hosting.Startup
}
return null;
}
if (returnType != null && methodInfo.ReturnType != returnType)
{
throw new Exception(string.Format("TODO: {0} method does not return " + returnType.Name,
methodInfo.Name));
if (required)
{
throw new Exception(string.Format("TODO: {0} method does not return " + returnType.Name,
methodInfo.Name));
}
return null;
}
return methodInfo;
}
private void Invoke(MethodInfo methodInfo, object instance, IApplicationBuilder builder, IServiceCollection services = null)
private object Invoke(MethodInfo methodInfo, object instance, IApplicationBuilder builder, IServiceCollection services = null)
{
var parameterInfos = methodInfo.GetParameters();
var parameters = new object[parameterInfos.Length];
@ -84,7 +86,7 @@ namespace Microsoft.AspNet.Hosting.Startup
}
}
}
methodInfo.Invoke(instance, parameters);
return methodInfo.Invoke(instance, parameters);
}
public Action<IApplicationBuilder> LoadStartup(
@ -137,8 +139,8 @@ namespace Microsoft.AspNet.Hosting.Startup
}
var configureMethod = FindMethod(type, "Configure{0}", environmentName, typeof(void), required: true);
// TODO: accept IServiceProvider method as well?
var servicesMethod = FindMethod(type, "Configure{0}Services", environmentName, typeof(void), required: false);
var servicesMethod = FindMethod(type, "Configure{0}Services", environmentName, typeof(IServiceProvider), required: false)
?? FindMethod(type, "Configure{0}Services", environmentName, typeof(void), required: false);
object instance = null;
if (!configureMethod.IsStatic || (servicesMethod != null && !servicesMethod.IsStatic))
@ -149,12 +151,22 @@ namespace Microsoft.AspNet.Hosting.Startup
{
if (servicesMethod != null)
{
var services = new ServiceCollection();
services.Add(OptionsServices.GetDefaultServices());
Invoke(servicesMethod, instance, builder, services);
if (builder != null)
if (servicesMethod.ReturnType == typeof(IServiceProvider))
{
builder.ApplicationServices = services.BuildServiceProvider(builder.ApplicationServices);
// IServiceProvider ConfigureServices()
builder.ApplicationServices = (Invoke(servicesMethod, instance, builder) as IServiceProvider)
?? builder.ApplicationServices;
}
else
{
// void ConfigureServices(IServiceCollection)
var services = new ServiceCollection();
services.Add(OptionsServices.GetDefaultServices());
Invoke(servicesMethod, instance, builder, services);
if (builder != null)
{
builder.ApplicationServices = services.BuildServiceProvider(builder.ApplicationServices);
}
}
}
Invoke(configureMethod, instance, builder);

View File

@ -3,6 +3,9 @@
using Microsoft.AspNet.Builder;
using Microsoft.Framework.DependencyInjection;
using Microsoft.Framework.DependencyInjection.Fallback;
using Microsoft.Framework.OptionsModel;
using System;
namespace Microsoft.AspNet.Hosting.Fakes
{
@ -44,6 +47,52 @@ namespace Microsoft.AspNet.Hosting.Fakes
});
}
public static IServiceProvider ConfigureStaticProviderServices()
{
var services = new ServiceCollection();
services.Add(OptionsServices.GetDefaultServices());
services.Configure<FakeOptions>(o =>
{
o.Configured = true;
o.Environment = "StaticProvider";
});
return services.BuildServiceProvider();
}
public static IServiceProvider ConfigureFallbackProviderServices(IServiceProvider fallback)
{
return fallback;
}
public static IServiceProvider ConfigureNullServices()
{
return null;
}
public IServiceProvider ConfigureProviderServices()
{
var services = new ServiceCollection();
services.Add(OptionsServices.GetDefaultServices());
services.Configure<FakeOptions>(o =>
{
o.Configured = true;
o.Environment = "Provider";
});
return services.BuildServiceProvider();
}
public IServiceProvider ConfigureProviderArgsServices(IApplicationBuilder me)
{
var services = new ServiceCollection();
services.Add(OptionsServices.GetDefaultServices());
services.Configure<FakeOptions>(o =>
{
o.Configured = true;
o.Environment = "ProviderArgs";
});
return services.BuildServiceProvider();
}
public virtual void Configure(IApplicationBuilder builder)
{
}

View File

@ -40,6 +40,9 @@ namespace Microsoft.AspNet.Hosting
[InlineData("Dev")]
[InlineData("Retail")]
[InlineData("Static")]
[InlineData("StaticProvider")]
[InlineData("Provider")]
[InlineData("ProviderArgs")]
public void StartupClassAddsConfigureServicesToApplicationServices(string environment)
{
var serviceCollection = new ServiceCollection();
@ -59,6 +62,25 @@ namespace Microsoft.AspNet.Hosting
Assert.Equal(environment, options.Environment);
}
[Theory]
[InlineData("Null")]
[InlineData("FallbackProvider")]
public void StartupClassConfigureServicesThatFallsbackToApplicationServices(string env)
{
var serviceCollection = new ServiceCollection();
serviceCollection.Add(HostingServices.GetDefaultServices());
var services = serviceCollection.BuildServiceProvider();
var manager = services.GetService<IStartupManager>();
var startup = manager.LoadStartup("Microsoft.AspNet.Hosting.Tests", env);
var app = new ApplicationBuilder(services);
startup.Invoke(app);
Assert.Equal(services, app.ApplicationServices);
}
[Fact]
public void StartupClassWithConfigureServicesAndUseServicesAddsBothToServices()
{