123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246 |
- using Autofac;
- using Autofac.Extensions.DependencyInjection;
- using FreeRedis;
- using FreeSql;
- using Microsoft.AspNetCore.Authentication;
- using Microsoft.AspNetCore.Authentication.JwtBearer;
- using Microsoft.AspNetCore.Mvc;
- using Microsoft.IdentityModel.Tokens;
- using Microsoft.OpenApi.Models;
- using Newtonsoft.Json;
- using Newtonsoft.Json.Serialization;
- using NLog.Web;
- using SM.Core;
- using SM.Model.SQL;
- using System.Reflection;
- using System.Text;
- namespace SM.Web
- {
- ///<summary>启动器</summary>
- public class Startup
- {
- ///<summary>执行方法</summary>
- public void Run(string[] args)
- {
- try
- {
- WebApplicationBuilder builder = WebApplication.CreateBuilder(args);
- builder.Logging.ClearProviders().SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Trace);
- builder.Host.UseNLog();
- IServiceCollection services = builder.Services;
- IWebHostEnvironment env = builder.Environment;
- builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory());
- AppConfig appConfig = ConfigHelper.Get<AppConfig>("AppConfig");
- services.AddSingleton(appConfig);
- WhiteListConfig whiteListConfig = ConfigHelper.Get<WhiteListConfig>("WhiteListConfig");
- services.AddSingleton(whiteListConfig);
- builder.WebHost.UseUrls(appConfig.Urls);
- for (int i = 0; i < appConfig.Urls.Length; i++)
- {
- LogHelper.Debug(appConfig.Urls[i]);
- }
- ConfigureServices(services, appConfig, env);
- builder.Host.ConfigureContainer<ContainerBuilder>(builder =>
- {
- ConfigureContainer(builder);
- });
- WebApplication app = builder.Build();
- Configure(app, appConfig);
- app.Run();
- }
- catch (Exception ex)
- {
- LogHelper.Error($"启动错误:{ex.Message}", ex);
- }
- }
- private void ConfigureServices(IServiceCollection services, AppConfig appConfig, IWebHostEnvironment env)
- {
- services.AddHttpClient();
- services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
- //自动映射
- Assembly serviceAssembly = Assembly.Load("SM.Services");
- services.AddAutoMapper(serviceAssembly);
- services.AddCors(options =>
- {
- options.AddPolicy("Cors", policy =>
- {
- if (appConfig.IsDebug)
- {
- policy
- .AllowAnyMethod()
- .SetIsOriginAllowed(_ => true)
- .AllowAnyHeader()
- .AllowCredentials();
- }
- else
- {
- policy
- .WithOrigins(appConfig.Cors)
- .AllowAnyHeader()
- .AllowAnyMethod()
- .AllowCredentials();
- }
- });
- });
- JwtConfig jwtConfig = ConfigHelper.Get<JwtConfig>("JwtConfig");
- services.AddSingleton(jwtConfig);
- services.AddAuthentication(options =>
- {
- options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
- options.DefaultChallengeScheme = nameof(ResponseAuthenticationHandler); //401
- options.DefaultForbidScheme = nameof(ResponseAuthenticationHandler); //403
- }).AddJwtBearer(options =>
- {
- options.TokenValidationParameters = new TokenValidationParameters
- {
- ValidateIssuer = true,
- ValidateAudience = true,
- ValidateLifetime = true,
- ValidateIssuerSigningKey = true,
- ValidIssuer = jwtConfig.Issuer,
- ValidAudience = jwtConfig.Audience,
- IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtConfig.SecurityKey)),
- ClockSkew = TimeSpan.Zero
- };
- }).AddScheme<AuthenticationSchemeOptions, ResponseAuthenticationHandler>(nameof(ResponseAuthenticationHandler), o => { });
- //内存
- //services.AddMemoryCache();
- //MySQL
- MySQLConfig mySQLConfig = ConfigHelper.Get<MySQLConfig>("MySQLConfig");
- Func<IServiceProvider, IFreeSql> fsqlFactory = r =>
- {
- IFreeSql fsql = new FreeSqlBuilder()
- .UseConnectionString(DataType.MySql, mySQLConfig.Connect)
- //.UseMonitorCommand(cmd => Console.WriteLine($"Sql:{cmd.CommandText}"))//监听SQL语句
- .UseAutoSyncStructure(true) //自动同步实体结构到数据库,FreeSql不会扫描程序集,只有CRUD时才会生成表。
- .Build();
- return fsql;
- };
- services.AddSingleton<IFreeSql>(fsqlFactory);
- //Redis
- RedisConfig redisConfig = ConfigHelper.Get<RedisConfig>("RedisConfig");
- RedisClient redis = new RedisClient(redisConfig.Connect)
- {
- Serialize = JsonConvert.SerializeObject,
- Deserialize = JsonConvert.DeserializeObject
- };
- services.AddSingleton(redis);
- //MongoDB
- //services.AddScoped<IMongoContext, MongoContext>();
- //services.AddScoped(typeof(IMongoRepository<>), typeof(MongoRepository<>));
- //设置输出的首字母大小写
- services.AddControllers().AddNewtonsoftJson(options =>
- {
- //忽略循环引用
- options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
- //默认属性输出
- options.SerializerSettings.ContractResolver = new DefaultContractResolver();
- //使用驼峰 首字母小写
- //options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
- //设置时间格式
- options.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:mm:ss";
- });
- //截取客户端提交的空参数
- services.Configure<ApiBehaviorOptions>(options =>
- {
- options.InvalidModelStateResponseFactory = actionContext =>
- {
- List<string> errors = actionContext.ModelState.Where(e => e.Value.Errors.Count > 0).Select(e => e.Value.Errors.First().ErrorMessage).ToList();
- string str = string.Join(" | ", errors);
- IResponseOutput response = ResponseOutput.NotOk(StatusCode.FieldNull_Error, str);
- return new BadRequestObjectResult(response);
- };
- });
- if (appConfig.IsDebug)
- {
- services.AddSwaggerGen(c =>
- {
- c.SwaggerDoc("v1", new OpenApiInfo { Title = "SM.Web", Version = "v1" });
- var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
- var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
- c.IncludeXmlComments(xmlPath);
- });
- }
- }
- private void ConfigureContainer(ContainerBuilder builder)
- {
- Assembly assemblyCore = Assembly.Load("SM.Core");
- builder.RegisterAssemblyTypes(assemblyCore).Where(t => t.GetCustomAttribute<SingleInstanceAttribute>() != null).SingleInstance();
- builder.RegisterAssemblyTypes(assemblyCore).Where(t => t.GetCustomAttribute<SingleInstanceAttribute>() != null).AsImplementedInterfaces().SingleInstance();
- var assemblyServices = Assembly.Load("SM.Services");
- builder.RegisterAssemblyTypes(assemblyServices).AsImplementedInterfaces().InstancePerLifetimeScope();
- }
- private void Configure(WebApplication app, AppConfig appConfig)
- {
- if (appConfig.IsDebug)
- {
- app.UseSwagger();
- app.UseSwaggerUI(c =>
- {
- c.SwaggerEndpoint("/swagger/v1/swagger.json", "SM.Web");
- });
- }
- //异常处理
- app.UseMiddleware<ExceptionMiddleware>();
- //路由
- app.UseRouting();
- //跨域
- app.UseCors("Cors");
- //认证
- app.UseAuthentication();
- //授权
- app.UseAuthorization();
- //默认访问
- //app.UseDefaultFiles();
- //静态文件访问(开启所以文件访问权限)
- //app.UseStaticFiles(new StaticFileOptions
- //{
- // ServeUnknownFileTypes = true
- //});
- if (!app.Environment.IsDevelopment())
- {
- //https
- app.UseHttpsRedirection();
- }
- //配置端点
- app.MapControllers();
- //在项目启动时,从容器中获取IFreeSql实例,并执行一些操作:同步表,种子数据,FluentAPI等
- using (IServiceScope serviceScope = app.Services.CreateScope())
- {
- var fsql = serviceScope.ServiceProvider.GetRequiredService<IFreeSql>();
- //同步的实体类
- fsql.CodeFirst.SyncStructure<AccountEntity>();
- }
- LogHelper.Debug("启动成功");
- }
- }
- }
|