Skip to content

Suggestions: ControllerMethodInvocationStrategy with Async Tasks and ASP.NET Core 3.x Endpoints #84

@JaronrH

Description

@JaronrH

Not really an issue but I wanted to submit back two possible enhancements that I made:

  1. Updated ControllerMethodInvocationStrategy to handle Tasks (async functions) in addition to normal functions:
    -Replaced-
    return await Task.Run(() => method.Invoke(Controller, args.ToArray()));
    -with-
                var result = await Task.Run(() => method.Invoke(Controller, args.ToArray()));
                if (result == null) return null;
                var resultType = result.GetType();
                if (resultType == typeof(Task)) return null;
                if (resultType.IsGenericType && resultType.GetGenericTypeDefinition() == typeof(Task<>))
                    return resultType.GetProperty("Result")?.GetValue(result);
                return result;
  1. Added a set of extension to allow WebSockManager to be used with Endpoints (ASP.NET Core 3.x):
public static class EndpointRouteBuilderExtensions
    {
        /// <summary>
        /// Add a WebSocketManager Handler that listens to a specific path.
        /// </summary>
        /// <typeparam name="THandler">Handler Type</typeparam>
        /// <param name="builder">Endpoint Builder</param>
        /// <param name="path">Path</param>
        /// <returns>Endpoint Convention Builder</returns>
        public static IEndpointConventionBuilder MapWebSocketManager<THandler>(this IEndpointRouteBuilder builder, string path)
            where THandler : WebSocketHandler
        {
            if (builder == null) throw new ArgumentNullException(nameof(builder));
            return builder.MapWebSocketManager(path, builder.ServiceProvider.GetRequiredService<THandler>());
        }

        /// <summary>
        /// Add a WebSocketManager Handler that listens to a specific path.
        /// </summary>
        /// <typeparam name="THandler">Handler Type</typeparam>
        /// <param name="builder">Endpoint Builder</param>
        /// <param name="path">Path</param>
        /// <param name="handlerFunc">Function that creates the Web Socket Handler</param>
        /// <returns>Endpoint Convention Builder</returns>
        public static IEndpointConventionBuilder MapWebSocketManager<THandler>(this IEndpointRouteBuilder builder, string path, Func<IServiceProvider,THandler> handlerFunc)
            where THandler : WebSocketHandler
        {
            if (builder == null) throw new ArgumentNullException(nameof(builder));
            return builder.MapWebSocketManager(path, handlerFunc(builder.ServiceProvider));
        }

        /// <summary>
        /// Add a WebSocketManager Handler that listens to a specific path.
        /// </summary>
        /// <typeparam name="THandler">Handler Type</typeparam>
        /// <param name="builder">Endpoint Builder</param>
        /// <param name="path">Path</param>
        /// <param name="handler">Web Socket Handler</param>
        /// <returns>Endpoint Convention Builder</returns>
        public static IEndpointConventionBuilder MapWebSocketManager<THandler>(this IEndpointRouteBuilder builder, string path, THandler handler) 
            where THandler : WebSocketHandler
        {
            if (builder == null) throw new ArgumentNullException(nameof(builder));
            if (string.IsNullOrEmpty(path)) throw new ArgumentNullException(nameof(path));
            if (handler == null) throw new ArgumentNullException(nameof(handler));
            return builder.Map(path, builder
                .CreateApplicationBuilder()
                .UseWebSockets()
                .UseMiddleware<WebSocketManagerMiddleware>(handler)
                .Build()
            );
        }

        /// <summary>
        /// Add a WebSocketManager Handler that listens to a specific path.
        /// </summary>
        /// <typeparam name="THandler">Handler Type</typeparam>
        /// <param name="builder">Endpoint Builder</param>
        /// <param name="routePattern">Route Pattern</param>
        /// <returns>Endpoint Convention Builder</returns>
        public static IEndpointConventionBuilder MapWebSocketManager<THandler>(this IEndpointRouteBuilder builder, RoutePattern routePattern)
            where THandler : WebSocketHandler
        {
            if (builder == null) throw new ArgumentNullException(nameof(builder));
            return builder.MapWebSocketManager(routePattern, builder.ServiceProvider.GetRequiredService<THandler>());
        }

        /// <summary>
        /// Add a WebSocketManager Handler that listens to a specific path.
        /// </summary>
        /// <typeparam name="THandler">Handler Type</typeparam>
        /// <param name="builder">Endpoint Builder</param>
        /// <param name="routePattern">Route Pattern</param>
        /// <param name="handlerFunc">Function that creates the Web Socket Handler</param>
        /// <returns>Endpoint Convention Builder</returns>
        public static IEndpointConventionBuilder MapWebSocketManager<THandler>(this IEndpointRouteBuilder builder, RoutePattern routePattern, Func<IServiceProvider, THandler> handlerFunc)
            where THandler : WebSocketHandler
        {
            if (builder == null) throw new ArgumentNullException(nameof(builder));
            return builder.MapWebSocketManager(routePattern, handlerFunc(builder.ServiceProvider));
        }

        /// <summary>
        /// Add a WebSocketManager Handler that listens to a specific path.
        /// </summary>
        /// <typeparam name="THandler">Handler Type</typeparam>
        /// <param name="builder">Endpoint Builder</param>
        /// <param name="routePattern">Route Pattern</param>
        /// <param name="handler">Web Socket Handler</param>
        /// <returns>Endpoint Convention Builder</returns>
        public static IEndpointConventionBuilder MapWebSocketManager<THandler>(this IEndpointRouteBuilder builder, RoutePattern routePattern, THandler handler)
            where THandler : WebSocketHandler
        {
            if (builder == null) throw new ArgumentNullException(nameof(builder));
            if (routePattern == null) throw new ArgumentNullException(nameof(routePattern));
            if (handler == null) throw new ArgumentNullException(nameof(handler));
            return builder.Map(routePattern, builder
                .CreateApplicationBuilder()
                .UseWebSockets()
                .UseMiddleware<WebSocketManagerMiddleware>(handler)
                .Build()
            );
        }
    }

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions