Throw when ConfigureServices has wrong signature

This commit is contained in:
Hao Kung 2015-05-15 13:46:58 -07:00
parent 89e60921f8
commit 5b851c49a3
8 changed files with 42 additions and 24 deletions

View File

@ -13,7 +13,7 @@ namespace Microsoft.AspNet.Hosting.Internal
internal static Tuple<string, string> SplitTypeName(string identifier) internal static Tuple<string, string> SplitTypeName(string identifier)
{ {
string typeName = null; string typeName = null;
string assemblyName = identifier.Trim(); var assemblyName = identifier.Trim();
var parts = identifier.Split(new[] { ',' }, 2); var parts = identifier.Split(new[] { ',' }, 2);
if (parts.Length == 2) if (parts.Length == 2)
{ {

View File

@ -39,7 +39,6 @@ namespace Microsoft.AspNet.Hosting.Internal
private IServiceProvider PriorRequestServices { get; set; } private IServiceProvider PriorRequestServices { get; set; }
private IServiceScope Scope { get; set; } private IServiceScope Scope { get; set; }
// CONSIDER: this could be an extension method on HttpContext instead // CONSIDER: this could be an extension method on HttpContext instead
public static RequestServicesContainer EnsureRequestServices(HttpContext httpContext, IServiceProvider services) public static RequestServicesContainer EnsureRequestServices(HttpContext httpContext, IServiceProvider services)
{ {

View File

@ -3,6 +3,8 @@
using System; using System;
using System.IO; using System.IO;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNet.Hosting.Internal; using Microsoft.AspNet.Hosting.Internal;
using Microsoft.Framework.ConfigurationModel; using Microsoft.Framework.ConfigurationModel;
using Microsoft.Framework.DependencyInjection; using Microsoft.Framework.DependencyInjection;

View File

@ -26,8 +26,8 @@ namespace Microsoft.AspNet.Hosting.Server
} }
var nameParts = HostingUtilities.SplitTypeName(serverFactoryIdentifier); var nameParts = HostingUtilities.SplitTypeName(serverFactoryIdentifier);
string typeName = nameParts.Item1; var typeName = nameParts.Item1;
string assemblyName = nameParts.Item2; var assemblyName = nameParts.Item2;
var assembly = Assembly.Load(new AssemblyName(assemblyName)); var assembly = Assembly.Load(new AssemblyName(assemblyName));
if (assembly == null) if (assembly == null)

View File

@ -20,10 +20,7 @@ namespace Microsoft.AspNet.Hosting.Startup
public MethodInfo MethodInfo { get; } public MethodInfo MethodInfo { get; }
public Action<IApplicationBuilder> Build(object instance) public Action<IApplicationBuilder> Build(object instance) => builder => Invoke(instance, builder);
{
return builder => Invoke(instance, builder);
}
private void Invoke(object instance, IApplicationBuilder builder) private void Invoke(object instance, IApplicationBuilder builder)
{ {

View File

@ -2,8 +2,10 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System; using System;
using System.Linq;
using System.Reflection; using System.Reflection;
using Microsoft.Framework.DependencyInjection; using Microsoft.Framework.DependencyInjection;
using Microsoft.Framework.Internal;
namespace Microsoft.AspNet.Hosting.Startup namespace Microsoft.AspNet.Hosting.Startup
{ {
@ -11,32 +13,33 @@ namespace Microsoft.AspNet.Hosting.Startup
public class ConfigureServicesBuilder public class ConfigureServicesBuilder
{ {
public ConfigureServicesBuilder(MethodInfo configureServices) public ConfigureServicesBuilder([NotNull] MethodInfo configureServices)
{ {
// Only support IServiceCollection parameters
var parameters = configureServices.GetParameters();
if (parameters.Length > 1 ||
parameters.Any(p => p.ParameterType != typeof(IServiceCollection)))
{
throw new InvalidOperationException("ConfigureServices can take at most a single IServiceCollection parameter.");
}
MethodInfo = configureServices; MethodInfo = configureServices;
} }
public MethodInfo MethodInfo { get; } public MethodInfo MethodInfo { get; }
public ConfigureServicesDelegate Build(object instance) public ConfigureServicesDelegate Build(object instance) => services => Invoke(instance, services);
{
return services => Invoke(instance, services);
}
private IServiceProvider Invoke(object instance, IServiceCollection exportServices) private IServiceProvider Invoke(object instance, [NotNull] IServiceCollection exportServices)
{ {
var parameterInfos = MethodInfo.GetParameters(); var parameters = new object[MethodInfo.GetParameters().Length];
var parameters = new object[parameterInfos.Length];
for (var index = 0; index != parameterInfos.Length; ++index) // Ctor ensures we have at most one IServiceCollection parameter
if (parameters.Length > 0)
{ {
var parameterInfo = parameterInfos[index]; parameters[0] = exportServices;
if (exportServices != null && parameterInfo.ParameterType == typeof(IServiceCollection))
{
parameters[index] = exportServices;
}
} }
// REVIEW: We null ref if exportServices is null, cuz it should not be null
return MethodInfo.Invoke(instance, parameters) as IServiceProvider ?? exportServices.BuildServiceProvider(); return MethodInfo.Invoke(instance, parameters) as IServiceProvider ?? exportServices.BuildServiceProvider();
} }
} }

View File

@ -82,7 +82,7 @@ namespace Microsoft.AspNet.Hosting.Fakes
return services.BuildServiceProvider(); return services.BuildServiceProvider();
} }
public IServiceProvider ConfigureProviderArgsServices(IApplicationBuilder me) public IServiceProvider ConfigureProviderArgsServices()
{ {
var services = new ServiceCollection().AddOptions(); var services = new ServiceCollection().AddOptions();
services.Configure<FakeOptions>(o => services.Configure<FakeOptions>(o =>

View File

@ -323,6 +323,23 @@ namespace Microsoft.AspNet.Hosting
} }
} }
[Fact]
public void HostingEngine_ThrowsForBadConfigureServiceSignature()
{
var engine = CreateBuilder()
.UseServer(this)
.UseStartup<BadConfigureServicesStartup>()
.Build();
var ex = Assert.Throws<InvalidOperationException>(() => engine.Start());
Assert.True(ex.Message.Contains("ConfigureServices"));
}
public class BadConfigureServicesStartup
{
public void ConfigureServices(IServiceCollection services, int gunk) { }
public void Configure(IApplicationBuilder app) { }
}
private IHostingEngine CreateHostingEngine(RequestDelegate requestDelegate) private IHostingEngine CreateHostingEngine(RequestDelegate requestDelegate)
{ {
var applicationBuilder = new Mock<IApplicationBuilder>(); var applicationBuilder = new Mock<IApplicationBuilder>();