using System; using EdjCase.JsonRpc.Core; using EdjCase.JsonRpc.Router; using EdjCase.JsonRpc.Router.Abstractions; using EdjCase.JsonRpc.Router.Defaults; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Microsoft.AspNetCore.Authorization; using Microsoft.Extensions.Options; using EdjCase.JsonRpc.Router.RouteProviders; using Microsoft.Extensions.DependencyInjection.Extensions; using EdjCase.JsonRpc.Core.Tools; using Microsoft.AspNetCore.Routing; using Microsoft.AspNetCore.Builder; using System.Net.WebSockets; // ReSharper disable once CheckNamespace namespace Microsoft.AspNetCore.Builder { /// /// Extension class to add JsonRpc router to Asp.Net pipeline /// public static class BuilderExtensions { /// /// Extension method to use the JsonRpc router in the Asp.Net pipeline /// /// that is supplied by Asp.Net /// Optional action to configure auto routing /// that includes the Basic auth middleware public static IApplicationBuilder UseJsonRpc(this IApplicationBuilder app, Action configureOptions = null) { if (app == null) { throw new ArgumentNullException(nameof(app)); } var options = new RpcAutoRoutingOptions(); configureOptions?.Invoke(options); IRpcRouteProvider routeProvider = new RpcAutoRouteProvider(Options.Create(options)); return app.UseJsonRpc(routeProvider); } /// /// Extension method to use the JsonRpc router in the Asp.Net pipeline /// /// that is supplied by Asp.Net /// Auto routing configuration /// that includes the Basic auth middleware public static IApplicationBuilder UseJsonRpc(this IApplicationBuilder app, RpcAutoRoutingOptions options) { if (app == null) { throw new ArgumentNullException(nameof(app)); } if (options == null) { throw new ArgumentNullException(nameof(options)); } IRpcRouteProvider routeProvider = new RpcAutoRouteProvider(Options.Create(options)); return app.UseJsonRpc(routeProvider); } /// /// Extension method to use the JsonRpc router in the Asp.Net pipeline /// /// that is supplied by Asp.Net /// Optional action to configure manual routing /// that includes the Basic auth middleware public static IApplicationBuilder UseManualJsonRpc(this IApplicationBuilder app, Action configureOptions = null) { if (app == null) { throw new ArgumentNullException(nameof(app)); } var options = new RpcManualRoutingOptions(); configureOptions?.Invoke(options); IRpcRouteProvider routeProvider = new RpcManualRouteProvider(Options.Create(options)); return app.UseJsonRpc(routeProvider); } /// /// Extension method to use the JsonRpc router in the Asp.Net pipeline /// /// that is supplied by Asp.Net /// Manual routing configuration /// that includes the Basic auth middleware public static IApplicationBuilder UseManualJsonRpc(this IApplicationBuilder app, RpcManualRoutingOptions options) { if (app == null) { throw new ArgumentNullException(nameof(app)); } if (options == null) { throw new ArgumentNullException(nameof(options)); } IRpcRouteProvider routeProvider = new RpcManualRouteProvider(Options.Create(options)); return app.UseJsonRpc(routeProvider); } /// /// Extension method to use the JsonRpc router in the Asp.Net pipeline /// /// that is supplied by Asp.Net /// Auto routing configuration /// that includes the Basic auth middleware public static IApplicationBuilder UseJsonRpc(this IApplicationBuilder app, IRpcRouteProvider routeProvider) { if (app == null) { throw new ArgumentNullException(nameof(app)); } if (routeProvider == null) { throw new ArgumentNullException(nameof(routeProvider)); } if (app.ApplicationServices.GetService() == null) { throw new InvalidOperationException("AddJsonRpc() needs to be called in the ConfigureServices method."); } var router = new RpcHttpRouter(routeProvider); return app.UseRouter(router); } /// /// Extension method to add the JsonRpc router services to the IoC container /// /// IoC serivce container to register JsonRpc dependencies /// IoC service container public static IRpcBuilder AddJsonRpc(this IServiceCollection serviceCollection) { if (serviceCollection == null) { throw new ArgumentNullException(nameof(serviceCollection)); } serviceCollection.AddSingleton(new RpcServicesMarker()); serviceCollection .TryAddScoped(); serviceCollection .TryAddScoped(); serviceCollection .TryAddScoped(); serviceCollection .TryAddScoped(); serviceCollection .TryAddScoped(); serviceCollection .TryAddScoped(); serviceCollection .TryAddScoped(); serviceCollection .AddRouting() .AddAuthorization(); return new RpcBuilder(serviceCollection); } } public interface IRpcBuilder { IServiceCollection Services { get; } } internal class RpcBuilder : IRpcBuilder { public IServiceCollection Services { get; } public RpcBuilder(IServiceCollection services) { this.Services = services; } } public class RpcServicesMarker { } public static class RpcBuilderExtensions { public static IRpcBuilder WithOptions(this IRpcBuilder builder, Action configureOptions) { var configuration = new RpcServerConfiguration(); configureOptions?.Invoke(configuration); builder.Services.Configure(configureOptions); return builder; } public static IRpcBuilder WithOptions(this IRpcBuilder builder, RpcServerConfiguration configuration) { builder.Services.AddSingleton>(Options.Create(configuration)); return builder; } public static IRpcBuilder WithParser(this IRpcBuilder builder) where T : class, IRpcParser { builder.Services.AddScoped(); return builder; } public static IRpcBuilder WithCompressor(this IRpcBuilder builder) where T : class, IStreamCompressor { builder.Services.AddScoped(); return builder; } public static IRpcBuilder WithReponseSerializer(this IRpcBuilder builder) where T : class, IRpcResponseSerializer { builder.Services.AddScoped(); return builder; } public static IRpcBuilder WithRequestMatcher(this IRpcBuilder builder) where T : class, IRpcRequestMatcher { builder.Services.AddScoped(); return builder; } } }