IApplicationBuilderExtensions.cs 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. using Grpc.Extension;
  2. using Grpc.Extension.Abstract;
  3. using Grpc.Extension.BaseService;
  4. using Grpc.Extension.Client;
  5. using Grpc.Extension.Common.Internal;
  6. using Microsoft.AspNetCore.Builder;
  7. using Microsoft.AspNetCore.Routing;
  8. using Microsoft.Extensions.Logging;
  9. using Microsoft.Extensions.Options;
  10. using Microsoft.Extensions.DependencyInjection;
  11. using OpenTracing;
  12. using OpenTracing.Util;
  13. using System;
  14. using System.Linq;
  15. using System.Runtime.InteropServices;
  16. namespace Grpc.Extension.AspNetCore
  17. {
  18. public static class IApplicationBuilderExtensions
  19. {
  20. /// <summary>
  21. /// 使用Grpc扩展
  22. /// </summary>
  23. /// <typeparam name="TStartup">实现IGrpcService的类所在程序集下的任意类</typeparam>
  24. /// <param name="builder"></param>
  25. /// <param name="configureOptions"></param>
  26. /// <returns></returns>
  27. public static IApplicationBuilder UseGrpcExtensions<TStartup>(this IApplicationBuilder builder, Action<GrpcExtensionsOptions> configureOptions = null)
  28. {
  29. ServiceProviderAccessor.SetServiceProvider(builder.ApplicationServices);
  30. //注入基本配制
  31. configureOptions?.Invoke(GrpcExtensionsOptions.Instance);
  32. //使用基础服务
  33. builder.UseEndpoints(endpoints => {
  34. endpoints.MapIGrpcServices<TStartup>();
  35. //使用基础服务
  36. endpoints.MapGrpcService<CmdService>();
  37. endpoints.MapGrpcService<MetaServiceAspnetCore>();
  38. });
  39. //默认使用
  40. builder.InitGrpcOptions()//初始化配制
  41. .UseLoggerFactory()//使用LoggerFactory
  42. .UseJaeger();//使用Jaeger
  43. return builder;
  44. }
  45. /// <summary>
  46. /// MapGrpcService(TStartup程序集下所有的IGrpcService)
  47. /// </summary>
  48. /// <typeparam name="TStartup">实现IGrpcService的类所在程序集下的任意类</typeparam>
  49. /// <param name="endpoints"></param>
  50. public static void MapIGrpcServices<TStartup>(this IEndpointRouteBuilder endpoints)
  51. {
  52. //获取所有IGrpcService并调用MapGrpcService方法
  53. var grpcServices = typeof(TStartup).Assembly.GetTypes().Where(p => typeof(IGrpcService).IsAssignableFrom(p) && p.IsClass);
  54. var method = typeof(GrpcEndpointRouteBuilderExtensions).GetMethod("MapGrpcService");
  55. foreach (var service in grpcServices)
  56. {
  57. var mapGrpcService = method.MakeGenericMethod(service);
  58. mapGrpcService.Invoke(null, new object[] { endpoints });
  59. }
  60. }
  61. /// <summary>
  62. /// 初始化配制
  63. /// </summary>
  64. /// <param name="builder"></param>
  65. /// <returns></returns>
  66. private static IApplicationBuilder InitGrpcOptions(this IApplicationBuilder builder)
  67. {
  68. var provider = builder.ApplicationServices;
  69. var serverOptions = provider.GetService<IOptions<GrpcServerOptions>>().Value;
  70. //Jaeger配置
  71. if (serverOptions.Jaeger != null && string.IsNullOrWhiteSpace(serverOptions.Jaeger.ServiceName))
  72. serverOptions.Jaeger.ServiceName = serverOptions.DiscoveryServiceName;
  73. #region 默认的客户端配制
  74. var clientOptions = provider.GetService<IOptions<GrpcClientOptions>>().Value;
  75. clientOptions.DiscoveryUrl = serverOptions.DiscoveryUrl;
  76. clientOptions.DefaultErrorCode = serverOptions.DefaultErrorCode;
  77. clientOptions.Jaeger = serverOptions.Jaeger;
  78. clientOptions.GrpcCallTimeOut = serverOptions.GrpcCallTimeOut;
  79. #endregion
  80. return builder;
  81. }
  82. /// <summary>
  83. /// 注入Grpc,Discovery配制
  84. /// </summary>
  85. /// <param name="builder"></param>
  86. /// <param name="configureOptions"></param>
  87. /// <returns></returns>
  88. public static IApplicationBuilder UseGrpcOptions(this IApplicationBuilder builder, Action<GrpcServerOptions> configureOptions)
  89. {
  90. var options = ServiceProviderAccessor.GetService<IOptions<GrpcServerOptions>>().Value;
  91. configureOptions(options);
  92. return builder;
  93. }
  94. /// <summary>
  95. /// 有Jaeger配制就使用Jaeger
  96. /// </summary>
  97. /// <param name="builder"></param>
  98. /// <returns></returns>
  99. private static IApplicationBuilder UseJaeger(this IApplicationBuilder builder)
  100. {
  101. var serverOptions = ServiceProviderAccessor.GetService<IOptions<GrpcServerOptions>>().Value;
  102. if (serverOptions.Jaeger != null && string.IsNullOrWhiteSpace(serverOptions.Jaeger.ServiceName))
  103. serverOptions.Jaeger.ServiceName = serverOptions.DiscoveryServiceName;
  104. if (serverOptions.Jaeger?.CheckConfig() == true)
  105. {
  106. var tracer = ServiceProviderAccessor.GetService<ITracer>();
  107. if (tracer != null) GlobalTracer.Register(tracer);
  108. }
  109. return builder;
  110. }
  111. /// <summary>
  112. /// 使用LoggerFactory
  113. /// </summary>
  114. /// <param name="builder"></param>
  115. /// <returns></returns>
  116. private static IApplicationBuilder UseLoggerFactory(this IApplicationBuilder builder)
  117. {
  118. var loggerFactory = ServiceProviderAccessor.GetService<ILoggerFactory>();
  119. var logger = loggerFactory.CreateLogger<IApplicationBuilder>();
  120. var loggerAccess = loggerFactory.CreateLogger("grpc.access");
  121. LoggerAccessor.Instance.LoggerError += (ex, type) => logger.LogError(ex.ToString());
  122. LoggerAccessor.Instance.LoggerMonitor += (msg, type) => loggerAccess.LogInformation(msg);
  123. return builder;
  124. }
  125. /// <summary>
  126. /// 配制日志(默认使用LoggerFactory)
  127. /// </summary>
  128. /// <param name="builder"></param>
  129. /// <param name="configureLogger"></param>
  130. /// <returns></returns>
  131. public static IApplicationBuilder UseLogger(this IApplicationBuilder builder, Action<LoggerAccessor> configureLogger)
  132. {
  133. configureLogger(LoggerAccessor.Instance);
  134. return builder;
  135. }
  136. /// <summary>
  137. /// CodeFirst生成proto文件
  138. /// </summary>
  139. /// <param name="builder"></param>
  140. /// <param name="dir">生成目录</param>
  141. /// <param name="spiltProto">是否拆分service和message协议</param>
  142. /// <returns></returns>
  143. public static IApplicationBuilder UseProtoGenerate(this IApplicationBuilder builder, string dir, bool spiltProto = true)
  144. {
  145. if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
  146. ProtoGenerator.Gen(dir, spiltProto);
  147. return builder;
  148. }
  149. }
  150. }