public void ValidConfigure_DoesNotThrow() { // Arrange var provider = new MiddlewareFilterConfigurationProvider(); // Act var configureDelegate = provider.CreateConfigureDelegate(typeof(ValidConfigure_WithNoEnvironment)); // Assert Assert.NotNull(configureDelegate); }
public void CreateConfigureDelegate_ThrowsIfTypeCannotBeInstantiated(Type configurationType) { // Arrange var provider = new MiddlewareFilterConfigurationProvider(); // Act var exception = Assert.Throws <InvalidOperationException>(() => provider.CreateConfigureDelegate(configurationType)); // Assert Assert.Equal($"Unable to create an instance of type '{configurationType}'. The type specified in configurationType must not be abstract and must have a parameterless constructor.", exception.Message); }
private RequestDelegate BuildPipeline(Type middlewarePipelineProviderType) { if (ApplicationBuilder == null) { throw new InvalidOperationException( Resources.FormatMiddlewareFilterBuilder_NullApplicationBuilder(nameof(ApplicationBuilder))); } var nestedAppBuilder = ApplicationBuilder.New(); // Get the 'Configure' method from the user provided type. var configureDelegate = _configurationProvider.CreateConfigureDelegate(middlewarePipelineProviderType); configureDelegate(nestedAppBuilder); // The middleware resource filter, after receiving the request executes the user configured middleware // pipeline. Since we want execution of the request to continue to later MVC layers (resource filters // or model binding), add a middleware at the end of the user provided pipeline which make sure to continue // this flow. // Example: // middleware filter -> user-middleware1 -> user-middleware2 -> end-middleware -> resource filters or model binding nestedAppBuilder.Run(async(httpContext) => { var feature = httpContext.Features.Get <IMiddlewareFilterFeature>(); if (feature == null) { throw new InvalidOperationException( Resources.FormatMiddlewareFilterBuilder_NoMiddlewareFeature(nameof(IMiddlewareFilterFeature))); } var resourceExecutionDelegate = feature.ResourceExecutionDelegate; var resourceExecutedContext = await resourceExecutionDelegate(); if (resourceExecutedContext.ExceptionHandled) { return; } // Ideally we want the experience of a middleware pipeline to behave the same as if it was registered // in Startup. In this scenario, an Exception thrown in a middleware later in the pipeline gets // propagated back to earlier middleware. So, check if a later resource filter threw an Exception and // propagate that back to the middleware pipeline. resourceExecutedContext.ExceptionDispatchInfo?.Throw(); if (resourceExecutedContext.Exception != null) { // This line is rarely reachable because ResourceInvoker captures thrown Exceptions using // ExceptionDispatchInfo. That said, filters could set only resourceExecutedContext.Exception. throw resourceExecutedContext.Exception; } }); return(nestedAppBuilder.Build()); }
public void InvalidType_NoPublicConfigure_Throws() { // Arrange var type = typeof(InvalidType_NoPublic_Configure); var provider = new MiddlewareFilterConfigurationProvider(); var expected = $"A public method named 'Configure' could not be found in the '{type.FullName}' type."; // Act & Assert var exception = Assert.Throws<InvalidOperationException>(() => { provider.CreateConfigureDelegate(type); }); Assert.Equal(expected, exception.Message); }
public void ValidConfigure_AndAdditionalServices_DoesNotThrow() { // Arrange var loggerFactory = Mock.Of<ILoggerFactory>(); var services = new ServiceCollection(); services.AddSingleton(loggerFactory); services.AddSingleton(Mock.Of<IHostingEnvironment>()); var applicationBuilder = GetApplicationBuilder(services); var provider = new MiddlewareFilterConfigurationProvider(); // Act var configureDelegate = provider.CreateConfigureDelegate(typeof(ValidConfigure_WithNoEnvironment_AdditionalServices)); // Assert Assert.NotNull(configureDelegate); }