BuilderExtensions.cs 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. using System;
  2. using EdjCase.JsonRpc.Core;
  3. using EdjCase.JsonRpc.Router;
  4. using EdjCase.JsonRpc.Router.Abstractions;
  5. using EdjCase.JsonRpc.Router.Defaults;
  6. using Microsoft.Extensions.DependencyInjection;
  7. using Microsoft.Extensions.Logging;
  8. using Microsoft.AspNetCore.Authorization;
  9. using Microsoft.Extensions.Options;
  10. using EdjCase.JsonRpc.Router.RouteProviders;
  11. using Microsoft.Extensions.DependencyInjection.Extensions;
  12. using EdjCase.JsonRpc.Core.Tools;
  13. using Microsoft.AspNetCore.Routing;
  14. using Microsoft.AspNetCore.Builder;
  15. using System.Net.WebSockets;
  16. // ReSharper disable once CheckNamespace
  17. namespace Microsoft.AspNetCore.Builder
  18. {
  19. /// <summary>
  20. /// Extension class to add JsonRpc router to Asp.Net pipeline
  21. /// </summary>
  22. public static class BuilderExtensions
  23. {
  24. /// <summary>
  25. /// Extension method to use the JsonRpc router in the Asp.Net pipeline
  26. /// </summary>
  27. /// <param name="app"><see cref="IApplicationBuilder"/> that is supplied by Asp.Net</param>
  28. /// <param name="configureOptions">Optional action to configure auto routing</param>
  29. /// <returns><see cref="IApplicationBuilder"/> that includes the Basic auth middleware</returns>
  30. public static IApplicationBuilder UseJsonRpc(this IApplicationBuilder app, Action<RpcAutoRoutingOptions> configureOptions = null)
  31. {
  32. if (app == null)
  33. {
  34. throw new ArgumentNullException(nameof(app));
  35. }
  36. var options = new RpcAutoRoutingOptions();
  37. configureOptions?.Invoke(options);
  38. IRpcRouteProvider routeProvider = new RpcAutoRouteProvider(Options.Create(options));
  39. return app.UseJsonRpc(routeProvider);
  40. }
  41. /// <summary>
  42. /// Extension method to use the JsonRpc router in the Asp.Net pipeline
  43. /// </summary>
  44. /// <param name="app"><see cref="IApplicationBuilder"/> that is supplied by Asp.Net</param>
  45. /// <param name="options">Auto routing configuration</param>
  46. /// <returns><see cref="IApplicationBuilder"/> that includes the Basic auth middleware</returns>
  47. public static IApplicationBuilder UseJsonRpc(this IApplicationBuilder app, RpcAutoRoutingOptions options)
  48. {
  49. if (app == null)
  50. {
  51. throw new ArgumentNullException(nameof(app));
  52. }
  53. if (options == null)
  54. {
  55. throw new ArgumentNullException(nameof(options));
  56. }
  57. IRpcRouteProvider routeProvider = new RpcAutoRouteProvider(Options.Create(options));
  58. return app.UseJsonRpc(routeProvider);
  59. }
  60. /// <summary>
  61. /// Extension method to use the JsonRpc router in the Asp.Net pipeline
  62. /// </summary>
  63. /// <param name="app"><see cref="IApplicationBuilder"/> that is supplied by Asp.Net</param>
  64. /// <param name="configureOptions">Optional action to configure manual routing</param>
  65. /// <returns><see cref="IApplicationBuilder"/> that includes the Basic auth middleware</returns>
  66. public static IApplicationBuilder UseManualJsonRpc(this IApplicationBuilder app, Action<RpcManualRoutingOptions> configureOptions = null)
  67. {
  68. if (app == null)
  69. {
  70. throw new ArgumentNullException(nameof(app));
  71. }
  72. var options = new RpcManualRoutingOptions();
  73. configureOptions?.Invoke(options);
  74. IRpcRouteProvider routeProvider = new RpcManualRouteProvider(Options.Create(options));
  75. return app.UseJsonRpc(routeProvider);
  76. }
  77. /// <summary>
  78. /// Extension method to use the JsonRpc router in the Asp.Net pipeline
  79. /// </summary>
  80. /// <param name="app"><see cref="IApplicationBuilder"/> that is supplied by Asp.Net</param>
  81. /// <param name="options">Manual routing configuration</param>
  82. /// <returns><see cref="IApplicationBuilder"/> that includes the Basic auth middleware</returns>
  83. public static IApplicationBuilder UseManualJsonRpc(this IApplicationBuilder app, RpcManualRoutingOptions options)
  84. {
  85. if (app == null)
  86. {
  87. throw new ArgumentNullException(nameof(app));
  88. }
  89. if (options == null)
  90. {
  91. throw new ArgumentNullException(nameof(options));
  92. }
  93. IRpcRouteProvider routeProvider = new RpcManualRouteProvider(Options.Create(options));
  94. return app.UseJsonRpc(routeProvider);
  95. }
  96. /// <summary>
  97. /// Extension method to use the JsonRpc router in the Asp.Net pipeline
  98. /// </summary>
  99. /// <param name="app"><see cref="IApplicationBuilder"/> that is supplied by Asp.Net</param>
  100. /// <param name="options">Auto routing configuration</param>
  101. /// <returns><see cref="IApplicationBuilder"/> that includes the Basic auth middleware</returns>
  102. public static IApplicationBuilder UseJsonRpc(this IApplicationBuilder app, IRpcRouteProvider routeProvider)
  103. {
  104. if (app == null)
  105. {
  106. throw new ArgumentNullException(nameof(app));
  107. }
  108. if (routeProvider == null)
  109. {
  110. throw new ArgumentNullException(nameof(routeProvider));
  111. }
  112. if (app.ApplicationServices.GetService<RpcServicesMarker>() == null)
  113. {
  114. throw new InvalidOperationException("AddJsonRpc() needs to be called in the ConfigureServices method.");
  115. }
  116. var router = new RpcHttpRouter(routeProvider);
  117. return app.UseRouter(router);
  118. }
  119. /// <summary>
  120. /// Extension method to add the JsonRpc router services to the IoC container
  121. /// </summary>
  122. /// <param name="serviceCollection">IoC serivce container to register JsonRpc dependencies</param>
  123. /// <returns>IoC service container</returns>
  124. public static IRpcBuilder AddJsonRpc(this IServiceCollection serviceCollection)
  125. {
  126. if (serviceCollection == null)
  127. {
  128. throw new ArgumentNullException(nameof(serviceCollection));
  129. }
  130. serviceCollection.AddSingleton(new RpcServicesMarker());
  131. serviceCollection
  132. .TryAddScoped<IRpcInvoker, DefaultRpcInvoker>();
  133. serviceCollection
  134. .TryAddScoped<IRpcParser, DefaultRpcParser>();
  135. serviceCollection
  136. .TryAddScoped<IRpcRequestHandler, RpcRequestHandler>();
  137. serviceCollection
  138. .TryAddScoped<IStreamCompressor, DefaultStreamCompressor>();
  139. serviceCollection
  140. .TryAddScoped<IRpcResponseSerializer, DefaultRpcResponseSerializer>();
  141. serviceCollection
  142. .TryAddScoped<IRpcRouteProvider, RpcAutoRouteProvider>();
  143. serviceCollection
  144. .TryAddScoped<IRpcRequestMatcher, DefaultRequestMatcher>();
  145. serviceCollection
  146. .AddRouting()
  147. .AddAuthorization();
  148. return new RpcBuilder(serviceCollection);
  149. }
  150. }
  151. public interface IRpcBuilder
  152. {
  153. IServiceCollection Services { get; }
  154. }
  155. internal class RpcBuilder : IRpcBuilder
  156. {
  157. public IServiceCollection Services { get; }
  158. public RpcBuilder(IServiceCollection services)
  159. {
  160. this.Services = services;
  161. }
  162. }
  163. public class RpcServicesMarker
  164. {
  165. }
  166. public static class RpcBuilderExtensions
  167. {
  168. public static IRpcBuilder WithOptions(this IRpcBuilder builder, Action<RpcServerConfiguration> configureOptions)
  169. {
  170. var configuration = new RpcServerConfiguration();
  171. configureOptions?.Invoke(configuration);
  172. builder.Services.Configure(configureOptions);
  173. return builder;
  174. }
  175. public static IRpcBuilder WithOptions(this IRpcBuilder builder, RpcServerConfiguration configuration)
  176. {
  177. builder.Services.AddSingleton<IOptions<RpcServerConfiguration>>(Options.Create(configuration));
  178. return builder;
  179. }
  180. public static IRpcBuilder WithParser<T>(this IRpcBuilder builder)
  181. where T : class, IRpcParser
  182. {
  183. builder.Services.AddScoped<IRpcParser, T>();
  184. return builder;
  185. }
  186. public static IRpcBuilder WithCompressor<T>(this IRpcBuilder builder)
  187. where T : class, IStreamCompressor
  188. {
  189. builder.Services.AddScoped<IStreamCompressor, T>();
  190. return builder;
  191. }
  192. public static IRpcBuilder WithReponseSerializer<T>(this IRpcBuilder builder)
  193. where T : class, IRpcResponseSerializer
  194. {
  195. builder.Services.AddScoped<IRpcResponseSerializer, T>();
  196. return builder;
  197. }
  198. public static IRpcBuilder WithRequestMatcher<T>(this IRpcBuilder builder)
  199. where T : class, IRpcRequestMatcher
  200. {
  201. builder.Services.AddScoped<IRpcRequestMatcher, T>();
  202. return builder;
  203. }
  204. }
  205. }