Remove target invocation exceptions from Startup invocation (#9318)
- This change takes advatage of the new DoNotWrapExceptions binding flag to avoid throwing a TargetInvocationException when invoking Configure/ConfigureServices and ConfigureContainer
This commit is contained in:
parent
0d45fe73d7
commit
717fa39167
|
|
@ -268,7 +268,7 @@ namespace Microsoft.AspNetCore.Hosting.Internal
|
|||
// _builder.ConfigureContainer<T>(ConfigureContainer);
|
||||
typeof(IHostBuilder).GetMethods().First(m => m.Name == nameof(IHostBuilder.ConfigureContainer))
|
||||
.MakeGenericMethod(containerType)
|
||||
.Invoke(_builder, new object[] { configureCallback });
|
||||
.InvokeWithoutWrappingExceptions(_builder, new object[] { configureCallback });
|
||||
}
|
||||
|
||||
// Resolve Configure after calling ConfigureServices and ConfigureContainer
|
||||
|
|
|
|||
|
|
@ -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.Globalization;
|
||||
using System.Reflection;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
|
@ -52,8 +53,9 @@ namespace Microsoft.AspNetCore.Hosting.Internal
|
|||
}
|
||||
}
|
||||
}
|
||||
MethodInfo.Invoke(instance, parameters);
|
||||
|
||||
MethodInfo.InvokeWithoutWrappingExceptions(instance, parameters);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
|
|
@ -46,7 +46,7 @@ namespace Microsoft.AspNetCore.Hosting.Internal
|
|||
|
||||
var arguments = new object[1] { container };
|
||||
|
||||
MethodInfo.Invoke(instance, arguments);
|
||||
MethodInfo.InvokeWithoutWrappingExceptions(instance, arguments);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ namespace Microsoft.AspNetCore.Hosting.Internal
|
|||
arguments[0] = services;
|
||||
}
|
||||
|
||||
return MethodInfo.Invoke(instance, arguments) as IServiceProvider;
|
||||
return MethodInfo.InvokeWithoutWrappingExceptions(instance, arguments) as IServiceProvider;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,20 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Reflection;
|
||||
|
||||
namespace Microsoft.AspNetCore.Hosting.Internal
|
||||
{
|
||||
internal static class MethodInfoExtensions
|
||||
{
|
||||
// This version of MethodInfo.Invoke removes TargetInvocationExceptions
|
||||
public static object InvokeWithoutWrappingExceptions(this MethodInfo methodInfo, object obj, object[] parameters)
|
||||
{
|
||||
// These are the default arguments passed when methodInfo.Invoke(obj, parameters) are called. We do the same
|
||||
// here but specify BindingFlags.DoNotWrapExceptions to avoid getting TAE (TargetInvocationException)
|
||||
// methodInfo.Invoke(obj, BindingFlags.Default, binder: null, parameters: parameters, culture: null)
|
||||
|
||||
return methodInfo.Invoke(obj, BindingFlags.DoNotWrapExceptions, binder: null, parameters: parameters, culture: null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -500,8 +500,36 @@ namespace Microsoft.AspNetCore.Hosting.Tests
|
|||
var app = new ApplicationBuilder(services);
|
||||
app.ApplicationServices = startup.ConfigureServicesDelegate(serviceCollection);
|
||||
|
||||
var ex = Assert.Throws<TargetInvocationException>(() => startup.ConfigureDelegate(app));
|
||||
Assert.IsAssignableFrom<InvalidOperationException>(ex.InnerException);
|
||||
Assert.Throws<InvalidOperationException>(() => startup.ConfigureDelegate(app));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ConfigureServicesThrowingDoesNotThrowTargetInvocationException()
|
||||
{
|
||||
var serviceCollection = new ServiceCollection();
|
||||
serviceCollection.AddSingleton<IServiceProviderFactory<IServiceCollection>, DefaultServiceProviderFactory>();
|
||||
var services = serviceCollection.BuildServiceProvider();
|
||||
|
||||
var startup = StartupLoader.LoadMethods(services, typeof(StartupConfigureServicesThrows), environmentName: null);
|
||||
|
||||
var app = new ApplicationBuilder(services);
|
||||
|
||||
Assert.Throws<Exception>(() => startup.ConfigureServicesDelegate(serviceCollection));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ConfigureThrowingDoesNotThrowTargetInvocationException()
|
||||
{
|
||||
var serviceCollection = new ServiceCollection();
|
||||
serviceCollection.AddSingleton<IServiceProviderFactory<IServiceCollection>, DefaultServiceProviderFactory>();
|
||||
var services = serviceCollection.BuildServiceProvider();
|
||||
|
||||
var startup = StartupLoader.LoadMethods(services, typeof(StartupConfigureThrows), environmentName: null);
|
||||
|
||||
var app = new ApplicationBuilder(services);
|
||||
app.ApplicationServices = startup.ConfigureServicesDelegate(serviceCollection);
|
||||
|
||||
Assert.Throws<Exception>(() => startup.ConfigureDelegate(app));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
|
|||
Loading…
Reference in New Issue