Skip to content
This repository was archived by the owner on Nov 20, 2018. It is now read-only.

UseMiddleware resolves InvokeAsync in addition to Invoke #804

Merged
merged 1 commit into from
Mar 27, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ namespace Microsoft.AspNetCore.Builder
/// </summary>
public static class UseMiddlewareExtensions
{
private const string InvokeMethodName = "Invoke";
internal const string InvokeMethodName = "Invoke";
internal const string InvokeAsyncMethodName = "InvokeAsync";

private static readonly MethodInfo GetServiceInfo = typeof(UseMiddlewareExtensions).GetMethod(nameof(GetService), BindingFlags.NonPublic | BindingFlags.Static);

Expand All @@ -44,7 +45,7 @@ public static IApplicationBuilder UseMiddleware(this IApplicationBuilder app, Ty
{
if (typeof(IMiddleware).GetTypeInfo().IsAssignableFrom(middleware.GetTypeInfo()))
{
// IMiddleware doesn't support passing args directly since it's
// IMiddleware doesn't support passing args directly since it's
// activated from the container
if (args.Length > 0)
{
Expand All @@ -58,27 +59,31 @@ public static IApplicationBuilder UseMiddleware(this IApplicationBuilder app, Ty
return app.Use(next =>
{
var methods = middleware.GetMethods(BindingFlags.Instance | BindingFlags.Public);
var invokeMethods = methods.Where(m => string.Equals(m.Name, InvokeMethodName, StringComparison.Ordinal)).ToArray();
var invokeMethods = methods.Where(m =>
string.Equals(m.Name, InvokeMethodName, StringComparison.Ordinal)
|| string.Equals(m.Name, InvokeAsyncMethodName, StringComparison.Ordinal)
).ToArray();

if (invokeMethods.Length > 1)
{
throw new InvalidOperationException(Resources.FormatException_UseMiddleMutlipleInvokes(InvokeMethodName));
throw new InvalidOperationException(Resources.FormatException_UseMiddleMutlipleInvokes(InvokeMethodName, InvokeAsyncMethodName));
}

if (invokeMethods.Length == 0)
{
throw new InvalidOperationException(Resources.FormatException_UseMiddlewareNoInvokeMethod(InvokeMethodName));
throw new InvalidOperationException(Resources.FormatException_UseMiddlewareNoInvokeMethod(InvokeMethodName, InvokeAsyncMethodName));
}

var methodinfo = invokeMethods[0];
if (!typeof(Task).IsAssignableFrom(methodinfo.ReturnType))
{
throw new InvalidOperationException(Resources.FormatException_UseMiddlewareNonTaskReturnType(InvokeMethodName, nameof(Task)));
throw new InvalidOperationException(Resources.FormatException_UseMiddlewareNonTaskReturnType(InvokeMethodName, InvokeAsyncMethodName, nameof(Task)));
}

var parameters = methodinfo.GetParameters();
if (parameters.Length == 0 || parameters[0].ParameterType != typeof(HttpContext))
{
throw new InvalidOperationException(Resources.FormatException_UseMiddlewareNoParameters(InvokeMethodName, nameof(HttpContext)));
throw new InvalidOperationException(Resources.FormatException_UseMiddlewareNoParameters(InvokeMethodName, InvokeAsyncMethodName, nameof(HttpContext)));
}

var ctorArgs = new object[args.Length + 1];
Expand Down Expand Up @@ -127,7 +132,7 @@ private static IApplicationBuilder UseMiddlewareInterface(IApplicationBuilder ap

try
{
await middleware.Invoke(context, next);
await middleware.InvokeAsync(context, next);
}
finally
{
Expand All @@ -140,12 +145,12 @@ private static IApplicationBuilder UseMiddlewareInterface(IApplicationBuilder ap
private static Func<T, HttpContext, IServiceProvider, Task> Compile<T>(MethodInfo methodinfo, ParameterInfo[] parameters)
{
// If we call something like
//
//
// public class Middleware
// {
// public Task Invoke(HttpContext context, ILoggerFactory loggeryFactory)
// {
//
//
// }
// }
//
Expand Down
6 changes: 1 addition & 5 deletions src/Microsoft.AspNetCore.Http.Abstractions/IMiddleware.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
// 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;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Microsoft.AspNetCore.Http
Expand All @@ -20,6 +16,6 @@ public interface IMiddleware
/// <param name="context">The <see cref="HttpContext"/> for the current request.</param>
/// <param name="next">The delegate representing the remaining middleware in the request pipeline.</param>
/// <returns>A <see cref="Task"/> that represents the execution of this middleware.</returns>
Task Invoke(HttpContext context, RequestDelegate next);
Task InvokeAsync(HttpContext context, RequestDelegate next);
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 4 additions & 4 deletions src/Microsoft.AspNetCore.Http.Abstractions/Resources.resx
Original file line number Diff line number Diff line change
Expand Up @@ -121,16 +121,16 @@
<value>'{0}' is not available.</value>
</data>
<data name="Exception_UseMiddlewareNoInvokeMethod" xml:space="preserve">
<value>No public '{0}' method found.</value>
<value>No public '{0}' or '{1}' method found.</value>
</data>
<data name="Exception_UseMiddlewareNonTaskReturnType" xml:space="preserve">
<value>'{0}' does not return an object of type '{1}'.</value>
<value>'{0}' or '{1}' does not return an object of type '{2}'.</value>
</data>
<data name="Exception_UseMiddlewareNoParameters" xml:space="preserve">
<value>The '{0}' method's first argument must be of type '{1}'.</value>
<value>The '{0}' or '{1}' method's first argument must be of type '{2}'.</value>
</data>
<data name="Exception_UseMiddleMutlipleInvokes" xml:space="preserve">
<value>Multiple public '{0}' methods are available.</value>
<value>Multiple public '{0}' or '{1}' methods are available.</value>
</data>
<data name="Exception_PathMustStartWithSlash" xml:space="preserve">
<value>The path in '{0}' must start with '/'.</value>
Expand Down
Loading