BusinessHostModule.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304
  1. using Autofac.Core;
  2. using Business.Core.MongoDBHelper;
  3. using Business.EntityFrameworkCore;
  4. using Business.MultiTenancy;
  5. using Business.Quartz;
  6. using Microsoft.AspNetCore.Authentication.JwtBearer;
  7. using Microsoft.AspNetCore.Builder;
  8. using Microsoft.AspNetCore.Cors;
  9. using Microsoft.AspNetCore.DataProtection;
  10. using Microsoft.AspNetCore.Hosting;
  11. using Microsoft.Extensions.Configuration;
  12. using Microsoft.Extensions.DependencyInjection;
  13. using Microsoft.Extensions.Hosting;
  14. using Microsoft.OpenApi.Models;
  15. using Quartz;
  16. using StackExchange.Redis;
  17. using System;
  18. using System.Collections.Generic;
  19. using System.Data;
  20. using System.IO;
  21. using System.Linq;
  22. using Volo.Abp;
  23. using Volo.Abp.AspNetCore.ExceptionHandling;
  24. using Volo.Abp.AspNetCore.MultiTenancy;
  25. using Volo.Abp.AspNetCore.Mvc;
  26. using Volo.Abp.AspNetCore.Serilog;
  27. using Volo.Abp.Autofac;
  28. using Volo.Abp.Caching;
  29. using Volo.Abp.Data;
  30. using Volo.Abp.EntityFrameworkCore.MySQL;
  31. using Volo.Abp.Localization;
  32. using Volo.Abp.Modularity;
  33. using Volo.Abp.MultiTenancy;
  34. using Volo.Abp.Threading;
  35. using Volo.Abp.VirtualFileSystem;
  36. namespace Business
  37. {
  38. [DependsOn(
  39. typeof(AbpAutofacModule),
  40. typeof(AbpEntityFrameworkCoreMySQLModule),
  41. typeof(BusinessHttpApiModule),
  42. typeof(BusinessApplicationModule),
  43. typeof(BusinessEntityFrameworkCoreModule),
  44. typeof(AbpAspNetCoreMultiTenancyModule),
  45. typeof(AbpAspNetCoreSerilogModule)
  46. )]
  47. public class BusinessHostModule : AbpModule
  48. {
  49. private const string DefaultCorsPolicyName = "Default";
  50. public override void ConfigureServices(ServiceConfigurationContext context)
  51. {
  52. var configuration = context.Services.GetConfiguration();
  53. var hostingEnvironment = context.Services.GetHostingEnvironment();
  54. //ConfigureConventionalControllers();
  55. ConfigureMultiTenancy();
  56. ConfigureAuthentication(context, configuration);
  57. ConfigureLocalization();
  58. ConfigureCache(configuration);
  59. ConfigureVirtualFileSystem(context, hostingEnvironment);
  60. //ConfigureRedis(context, configuration, hostingEnvironment);
  61. ConfigureCors(context, configuration);
  62. ConfigureSwaggerServices(context, configuration);
  63. ConfigureQuartz(context, configuration);
  64. //MongoDB依赖注入
  65. ConfigureMongoDB(configuration);
  66. if (hostingEnvironment.IsDevelopment())
  67. {
  68. Configure<AbpExceptionHandlingOptions>(options =>
  69. {
  70. options.SendExceptionsDetailsToClients = true;
  71. });
  72. }
  73. }
  74. private void ConfigureConventionalControllers()
  75. {
  76. Configure<AbpAspNetCoreMvcOptions>(options =>
  77. {
  78. options.ConventionalControllers.Create(typeof(BusinessApplicationModule).Assembly);
  79. });
  80. }
  81. private void ConfigureMultiTenancy()
  82. {
  83. Configure<AbpMultiTenancyOptions>(options =>
  84. {
  85. options.IsEnabled = true;
  86. });
  87. }
  88. private void ConfigureQuartz(ServiceConfigurationContext context, IConfiguration configuration)
  89. {
  90. context.Services.AddQuartz(q =>
  91. {
  92. q.UseMicrosoftDependencyInjectionScopedJobFactory();
  93. // Just use the name of your job that you created in the Jobs folder.
  94. var jobKey = new JobKey("DemoJob");
  95. q.AddJob<SyncMySQLDataJob>(opts => opts.WithIdentity(jobKey));
  96. q.AddTrigger(opts => opts
  97. .ForJob(jobKey)
  98. .WithIdentity("DemoJob-trigger")
  99. .WithCronSchedule("0 45 11 * * ?")
  100. .WithDescription("定时同步MySQL基础数据到MongoDB"));
  101. });
  102. context.Services.AddQuartzServer(options =>
  103. {
  104. // when shutting down we want jobs to complete gracefully
  105. options.WaitForJobsToComplete = true;
  106. });
  107. //context.Services.AddQuartzHostedService(options =>
  108. //{
  109. // // when shutting down we want jobs to complete gracefully
  110. // options.WaitForJobsToComplete = true;
  111. //});
  112. }
  113. /// <summary>
  114. /// MongoDB依赖注入
  115. /// </summary>
  116. /// <param name="context"></param>
  117. /// <param name="configuration"></param>
  118. private void ConfigureMongoDB(IConfiguration configuration)
  119. {
  120. Configure<Config>(options =>
  121. {
  122. options.connectstring = configuration.GetConnectionString("MongoDB");
  123. options.database = configuration.GetConnectionString("DBName");
  124. });
  125. }
  126. private void ConfigureCache(IConfiguration configuration)
  127. {
  128. Configure<AbpDistributedCacheOptions>(options =>
  129. {
  130. options.KeyPrefix = "dopbiz:";
  131. });
  132. }
  133. private void ConfigureVirtualFileSystem(ServiceConfigurationContext context, IWebHostEnvironment webHostEnvironment)
  134. {
  135. //var hostingEnvironment = context.Services.GetHostingEnvironment();
  136. if (webHostEnvironment.IsDevelopment())
  137. {
  138. Configure<AbpVirtualFileSystemOptions>(options =>
  139. {
  140. options.FileSets.ReplaceEmbeddedByPhysical<BusinessDomainModule>(Path.Combine(webHostEnvironment.ContentRootPath, $"..{Path.DirectorySeparatorChar}Business.Domain"));
  141. options.FileSets.ReplaceEmbeddedByPhysical<BusinessApplicationContractsModule>(Path.Combine(webHostEnvironment.ContentRootPath, $"..{Path.DirectorySeparatorChar}Business.Application.Contracts"));
  142. options.FileSets.ReplaceEmbeddedByPhysical<BusinessApplicationModule>(Path.Combine(webHostEnvironment.ContentRootPath, $"..{Path.DirectorySeparatorChar}Business.Application"));
  143. });
  144. }
  145. }
  146. private void ConfigureAuthentication(ServiceConfigurationContext context, IConfiguration configuration)
  147. {
  148. context.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
  149. .AddJwtBearer(options =>
  150. {
  151. options.Authority = configuration["AuthServer:Authority"];
  152. options.RequireHttpsMetadata = false;
  153. options.Audience = "BusinessService";
  154. });
  155. }
  156. private static void ConfigureSwaggerServices(ServiceConfigurationContext context, IConfiguration configuration)
  157. {
  158. if (configuration["UseSwagger"] == "true")
  159. {
  160. context.Services.AddSwaggerGen(options =>
  161. {
  162. options.SwaggerDoc("v1", new OpenApiInfo { Title = "Business Service API", Version = "v1" });
  163. options.DocInclusionPredicate((docName, description) => true);
  164. options.CustomSchemaIds(type => type.FullName);
  165. options.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
  166. {
  167. Description = "请输入JWT令牌,例如:Bearer 12345abcdef",
  168. Name = "Authorization",
  169. In = ParameterLocation.Header,
  170. Type = SecuritySchemeType.ApiKey,
  171. Scheme = "Bearer"
  172. });
  173. options.AddSecurityRequirement(new OpenApiSecurityRequirement()
  174. {
  175. {
  176. new OpenApiSecurityScheme
  177. {
  178. Reference = new OpenApiReference
  179. {
  180. Type = ReferenceType.SecurityScheme,
  181. Id = "Bearer"
  182. },
  183. Scheme = "oauth2",
  184. Name = "Bearer",
  185. In = ParameterLocation.Header,
  186. },
  187. new List<string>()
  188. }
  189. });
  190. });
  191. }
  192. }
  193. private void ConfigureLocalization()
  194. {
  195. Configure<AbpLocalizationOptions>(options =>
  196. {
  197. options.Languages.Add(new LanguageInfo("cs", "cs", "Čeština"));
  198. options.Languages.Add(new LanguageInfo("en", "en", "English"));
  199. options.Languages.Add(new LanguageInfo("pt-BR", "pt-BR", "Português"));
  200. options.Languages.Add(new LanguageInfo("tr", "tr", "Türkçe"));
  201. options.Languages.Add(new LanguageInfo("zh-Hans", "zh-Hans", "简体中文"));
  202. options.Languages.Add(new LanguageInfo("zh-Hant", "zh-Hant", "繁體中文"));
  203. });
  204. }
  205. private void ConfigureRedis(
  206. ServiceConfigurationContext context,
  207. IConfiguration configuration,
  208. IWebHostEnvironment hostingEnvironment)
  209. {
  210. context.Services.AddStackExchangeRedisCache(options =>
  211. {
  212. options.Configuration = configuration["Redis:Configuration"];
  213. });
  214. if (!hostingEnvironment.IsDevelopment())
  215. {
  216. var redis = ConnectionMultiplexer.Connect(configuration["Redis:Configuration"]);
  217. context.Services
  218. .AddDataProtection()
  219. .PersistKeysToStackExchangeRedis(redis, "DataProtection-Keys");
  220. }
  221. }
  222. private void ConfigureCors(ServiceConfigurationContext context, IConfiguration configuration)
  223. {
  224. context.Services.AddCors(options =>
  225. {
  226. options.AddPolicy(DefaultCorsPolicyName, builder =>
  227. {
  228. builder
  229. .WithOrigins(
  230. configuration["App:CorsOrigins"]
  231. .Split(",", StringSplitOptions.RemoveEmptyEntries)
  232. .Select(o => o.RemovePostFix("/"))
  233. .ToArray()
  234. )
  235. .WithAbpExposedHeaders()
  236. .SetIsOriginAllowedToAllowWildcardSubdomains()
  237. .AllowAnyHeader()
  238. .AllowAnyMethod()
  239. .AllowCredentials();
  240. });
  241. });
  242. }
  243. public override void OnApplicationInitialization(ApplicationInitializationContext context)
  244. {
  245. var app = context.GetApplicationBuilder();
  246. var configuration = context.GetConfiguration();
  247. app.UseCorrelationId();
  248. app.UseStaticFiles();
  249. app.UseRouting();
  250. app.UseCors(DefaultCorsPolicyName);
  251. app.UseAuthentication();
  252. app.UseAbpClaimsMap();
  253. if (MultiTenancyConsts.IsEnabled)
  254. {
  255. app.UseMultiTenancy();
  256. }
  257. app.UseAbpRequestLocalization();
  258. if (configuration["UseSwagger"] == "true")
  259. {
  260. app.UseSwagger();
  261. app.UseSwaggerUI(options =>
  262. {
  263. options.SwaggerEndpoint("/swagger/v1/swagger.json", "Business Service API");
  264. });
  265. }
  266. app.UseAuditing();
  267. app.UseAbpSerilogEnrichers();
  268. app.UseUnitOfWork();
  269. app.UseConfiguredEndpoints();
  270. AsyncHelper.RunSync(async () =>
  271. {
  272. using (var scope = context.ServiceProvider.CreateScope())
  273. {
  274. await scope.ServiceProvider
  275. .GetRequiredService<IDataSeeder>()
  276. .SeedAsync();
  277. }
  278. });
  279. }
  280. }
  281. }