예제 #1
0
    public void CreateConfigureDelegate_ThrowsIfTypeCannotBeInstantiated(Type configurationType)
    {
        // Arrange
        var provider = new MiddlewareFilterConfigurationProvider();

        // Act
        var exception = Assert.Throws <InvalidOperationException>(() => MiddlewareFilterConfigurationProvider.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);
    }
예제 #2
0
    public void ValidConfigure_DoesNotThrow()
    {
        // Arrange
        var provider = new MiddlewareFilterConfigurationProvider();

        // Act
        var configureDelegate = MiddlewareFilterConfigurationProvider.CreateConfigureDelegate(typeof(ValidConfigure_WithNoEnvironment));

        // Assert
        Assert.NotNull(configureDelegate);
    }
예제 #3
0
    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());
    }
예제 #4
0
    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>(() =>
        {
            MiddlewareFilterConfigurationProvider.CreateConfigureDelegate(type);
        });

        Assert.Equal(expected, exception.Message);
    }
예제 #5
0
    public void ValidConfigure_AndAdditionalServices_DoesNotThrow()
    {
        // Arrange
        var loggerFactory = Mock.Of <ILoggerFactory>();
        var services      = new ServiceCollection();

        services.AddSingleton(loggerFactory);
        services.AddSingleton(Mock.Of <IWebHostEnvironment>());
        var applicationBuilder = GetApplicationBuilder(services);
        var provider           = new MiddlewareFilterConfigurationProvider();

        // Act
        var configureDelegate = MiddlewareFilterConfigurationProvider.CreateConfigureDelegate(typeof(ValidConfigure_WithNoEnvironment_AdditionalServices));

        // Assert
        Assert.NotNull(configureDelegate);
    }