public static IHost Update <TContext>(this IHost host, Action <TContext, IServiceProvider> seeder = null) where TContext : DbContext { using var scope = host.Services.CreateScope(); var services = scope.ServiceProvider; var logger = services.GetRequiredService <ILogger <TContext> >(); var context = services.GetService <TContext>(); try { logger.LogInformation($"Migrating database associated with context {typeof(TContext).Name}"); AsyncHelper.TryAsync(async() => { if (EntryExtends.IsInUT()) { await context.Database.EnsureDeletedAsync(); } else { await context.Database.MigrateAsync(); } seeder?.Invoke(context, services); }, 3, (e) => { logger.LogCritical(e, "Update database failed."); }); logger.LogInformation($"Updated database associated with context {typeof(TContext).Name}"); } catch (Exception ex) { logger.LogError(ex, $"An error occurred while migrating the database used on context {typeof(TContext).Name}"); } return(host); }
public static IServiceCollection AddAiursoftSDK(this IServiceCollection services, Assembly assembly = null, params Type[] abstracts) { services.AddHttpClient(); services.AddMemoryCache(); var abstractsArray = abstracts .AddWith(typeof(IHostedService)) .AddWith(typeof(ISeeder)) .ToArray(); if (EntryExtends.IsProgramEntry()) { // Program is starting itself. services.AddScannedDependencies(abstractsArray); } else if (assembly != null) { // Program is started in UT or EF. Method called from extension. services.AddAssemblyDependencies(assembly, abstractsArray); } else { // Program is started in UT or EF. Method called from web project. services.AddAssemblyDependencies(Assembly.GetCallingAssembly(), abstractsArray); } return(services); }
public static IServiceCollection AddDbContextWithCache <T>(this IServiceCollection services, string connectionString) where T : DbContext { if (EntryExtends.IsInUT()) { services.AddDbContext <T>((serviceProvider, optionsBuilder) => optionsBuilder .UseInMemoryDatabase("inmemory") .AddInterceptors(serviceProvider.GetRequiredService <SecondLevelCacheInterceptor>())); // Consider some new EF technology like use memory cache. } else { services.AddDbContextPool <T>((serviceProvider, optionsBuilder) => optionsBuilder .UseSqlServer(connectionString) .AddInterceptors(serviceProvider.GetRequiredService <SecondLevelCacheInterceptor>())); } services.AddEFSecondLevelCache(options => { options.UseMemoryCacheProvider().DisableLogging(true); options.CacheAllQueries(CacheExpirationMode.Sliding, TimeSpan.FromMinutes(30)); }); return(services); }
public Task StartAsync(CancellationToken cancellationToken) { if (_env.IsDevelopment() || !EntryExtends.IsProgramEntry()) { _logger.LogInformation("Skip cleaner in development environment."); return(Task.CompletedTask); } _logger.LogInformation("Timed Background Service is starting."); _timer = new Timer(DoWork, null, TimeSpan.FromSeconds(30), TimeSpan.FromMinutes(15)); return(Task.CompletedTask); }
public Task StartAsync(CancellationToken cancellationToken) { if (_env.IsDevelopment() || !EntryExtends.IsProgramEntry()) { _logger.LogInformation("Skip cleaner in development environment."); return(Task.CompletedTask); } _logger.LogInformation("Timed Background Service is starting."); // Start cleaner after one day. // Because when stargate starts, all channels are treated dead. _timer = new Timer(DoWork, null, TimeSpan.FromDays(1), TimeSpan.FromMinutes(10)); return(Task.CompletedTask); }
public static IApplicationBuilder UseAiurAPIHandler(this IApplicationBuilder app, bool isDevelopment) { if (isDevelopment || !EntryExtends.IsProgramEntry()) { app.UseDeveloperExceptionPage(); } else { app.UseMiddleware <HandleRobotsMiddleware>(); app.UseForwardedHeaders(new ForwardedHeadersOptions { ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto }); app.UseMiddleware <EnforceHttpsMiddleware>(); app.UseMiddleware <APIFriendlyServerExceptionMiddleware>(); } return(app); }
public static IServiceCollection AddAiursoftSDK(this IServiceCollection services, Assembly assembly = null, params Type[] abstracts) { services.AddHttpClient(); services.AddMemoryCache(); var abstractsArray = abstracts.AddWith(typeof(IHostedService)).ToArray(); if (EntryExtends.IsProgramEntry()) { services.AddScannedDependencies(abstractsArray); } else if (assembly != null) { services.AddAssemblyDependencies(assembly, abstractsArray); } else { services.AddAssemblyDependencies(Assembly.GetCallingAssembly(), abstractsArray); } return(services); }
public override void OnActionExecuting(ActionExecutingContext context) { base.OnActionExecuting(context); if (IPAddress.IsLoopback(context.HttpContext.Connection.RemoteIpAddress) && !EntryExtends.IsInUT()) { return; } if (DateTime.UtcNow - LastClearTime > TimeSpan.FromMinutes(1)) { ClearMemory(); LastClearTime = DateTime.UtcNow; } var tempDictionary = Copy(); var path = context.HttpContext.Request.Path.ToString().ToLower(); var ip = context.HttpContext.Connection.RemoteIpAddress.ToString(); if (tempDictionary.ContainsKey(ip + path)) { WriteMemory(ip + path, tempDictionary[ip + path] + 1); if (tempDictionary[ip + path] > _limit) { context.HttpContext.Response.Headers.Add("retry-after", (60 - (int)(DateTime.UtcNow - LastClearTime).TotalSeconds).ToString()); context.HttpContext.Response.StatusCode = (int)HttpStatusCode.TooManyRequests; if (ReturnJson) { context.Result = new JsonResult(new AiurProtocol { Code = ErrorType.TooManyRequests, Message = "You are requesting our API too frequently and your IP is blocked." }); } else { context.Result = new StatusCodeResult((int)HttpStatusCode.TooManyRequests); } } } else { tempDictionary[ip + path] = 1; WriteMemory(ip + path, 1); } context.HttpContext.Response.Headers.Add("x-rate-limit-limit", "1m"); context.HttpContext.Response.Headers.Add("x-rate-limit-remaining", (_limit - tempDictionary[ip + path]).ToString()); }