// This method gets called by the runtime. Use this method to add services to the container. // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940 public void ConfigureServices(IServiceCollection services) { services.AddControllersWithViews(); services.AddRazorPages(); services.AddSignalR(); // TODO: Change the ServiceLifetime. The usage of ServiceLifetime.Transient is because multiple threads operations are running in the same dbcontext. services.AddDbContext <DbContext, ApplicationDbContext>(ServiceLifetime.Transient); services.AddOrcEntityFrameworkCore(); services.AddDatabaseSeeder <ApplicationDbSeeder>(); var token = this.Configuration.GetSection("TelegramBot")?["Token"]; if (!string.IsNullOrWhiteSpace(token)) { if (token == "%TELEGRAM_BOT_TOKEN%") { Log.Warning( "Telegram notification is disable. Replace %TELEGRAM_BOT_TOKEN% placeholder in the configuration file with a valid bot token."); } else { Log.Information("Telegram notification is enable."); services.AddTransient <ITelegramBotClient>(sp => new TelegramBotClient(token)); services.AddSingleton <ITelegramCommander, TelegramCommander>(); } } else { Log.Warning( "Telegram notification is disable. To enable it, add a TelegramBot section with a key Token."); } services.AddTransient(sp => new CookieContainer()); services.AddTransient(sp => BrowsingContext.New(AngleSharp.Configuration.Default)); services.AddTransient( sp => { var cookieContainer = sp.GetService <CookieContainer>(); var handler = new HttpClientHandler { AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate | DecompressionMethods.Brotli, AllowAutoRedirect = true }; if (cookieContainer != null) { handler.CookieContainer = cookieContainer; // TODO: Review how to avoid the call to .GetAwaiter().GetResult() var cookieCollection = CookiesHelper.GetCollectitonAsync().GetAwaiter().GetResult(); if (cookieCollection.Count > 0) { handler.CookieContainer.Add(new Uri("https://www.tuenvio.cu"), cookieCollection); } } var httpClient = new HttpClient(handler) { Timeout = ScrappingConfiguration.HttpClientTimeout }; httpClient.DefaultRequestHeaders.TryAddWithoutValidation( "user-agent", ScrappingConfiguration.Agent); httpClient.DefaultRequestHeaders.TryAddWithoutValidation( "accept-encoding", "gzip, deflate, br"); httpClient.DefaultRequestHeaders.CacheControl = new CacheControlHeaderValue { NoCache = true }; return(httpClient); }); // services.AddHttpClient( // "json", // (sp, httpClient) => // { // httpClient.Timeout = ScrappingConfiguration.HttpClientTimeout; // httpClient.DefaultRequestHeaders.CacheControl = // new CacheControlHeaderValue { NoCache = true }; // httpClient.DefaultRequestHeaders.TryAddWithoutValidation( // "user-agent", // "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36"); // }); services.AddScoped <IStoreService, StoreService>(); services.AddSingleton <ICacheStorage <string, Product> >( provider => new CacheStorage <string, Product>(storeNullValues: true)); services.AddSingleton <ICacheStorage <string, Department> >( provider => new CacheStorage <string, Department>(storeNullValues: true)); services.AddSingleton <ICacheStorage <string, Store> >( provider => new CacheStorage <string, Store>(storeNullValues: true)); services.AddTransient <IEntityScrapper <Product>, ProductScrapper>(); services.AddTransient <IEntityScrapper <Department>, DepartmentScrapper>(); services.AddTransient <IEntityScrapper <Store>, StoreScrapper>(); services.AddTransient <IMultiEntityScrapper <Product>, InspectDepartmentProductsScrapper>(); services.AddTransient <IMultiEntityScrapper <Department>, InspectStoreDepartmentsScrapper>(); services.AddSingleton <ImportStoresHostedService>(); services.AddHostedService <DepartmentMonitorHostedService>(); services.AddHostedService <ProductMonitorHostedService>(); services.AddHostedService <StoreMonitorHostedService>(); // services.AddHostedService<SyncUsersFromTelegramHostedService>(); }