public async Task InternalHttpRetryPolicy_CorrectWaitTimesAreUsedWhenServiceUnavailable() { _pollyHttpPoliciesConfig.SetupGet(x => x.AzureFunctionNotStartedPauses).Returns(new TimeSpan[0]); _serviceCaller = new Mock <IServiceCaller>(); _serviceCaller.SetupSequence(x => x.GetAsync()) .ReturnsAsync(new HttpResponseMessage(HttpStatusCode.BadGateway)) .ReturnsAsync(new HttpResponseMessage(HttpStatusCode.BadGateway)) .ReturnsAsync(new HttpResponseMessage(HttpStatusCode.ServiceUnavailable)) .ReturnsAsync(new HttpResponseMessage(HttpStatusCode.OK)); PollyHttpPolicies pollyHttpPolicies = new PollyHttpPolicies(_pollyHttpPoliciesConfig.Object); HttpResponseMessage result = await pollyHttpPolicies.InternalHttpRetryPolicy.ExecuteAsync(async() => await _serviceCaller.Object.GetAsync()); Assert.AreEqual(503, (int)result.StatusCode); // shows the correct wait times were used for ServiceUnavailable (since it was empty the ServiceUnavailable is returned) }
public async Task ExternalHttpRetryPolicy() { _serviceCaller = new Mock <IServiceCaller>(); _serviceCaller.SetupSequence(x => x.GetAsync()) .ReturnsAsync(new HttpResponseMessage(HttpStatusCode.RequestTimeout)) .ReturnsAsync(new HttpResponseMessage(HttpStatusCode.InternalServerError)) .ReturnsAsync(new HttpResponseMessage(HttpStatusCode.BadGateway)) .ReturnsAsync(new HttpResponseMessage(HttpStatusCode.ServiceUnavailable)) .ReturnsAsync(new HttpResponseMessage(HttpStatusCode.GatewayTimeout)) .ReturnsAsync(new HttpResponseMessage(HttpStatusCode.InsufficientStorage)) .ReturnsAsync(new HttpResponseMessage(HttpStatusCode.OK)); PollyHttpPolicies pollyHttpPolicies = new PollyHttpPolicies(_pollyHttpPoliciesConfig.Object); HttpResponseMessage result = await pollyHttpPolicies.ExternalHttpRetryPolicy.ExecuteAsync(async() => await _serviceCaller.Object.GetAsync()); Assert.AreEqual(200, (int)result.StatusCode); }
public override void Configure(IFunctionsHostBuilder builder) { // We need to get the app directory this way. Using Environment.CurrentDirectory doesn't work in Azure. ExecutionContextOptions executioncontextoptions = builder.Services.BuildServiceProvider() .GetService <IOptions <ExecutionContextOptions> >().Value; string currentDirectory = executioncontextoptions.AppDirectory; var config = new ConfigurationBuilder() .SetBasePath(currentDirectory) .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true) .AddJsonFile("local.settings.json", true) .AddEnvironmentVariables().Build(); // DI doesn't work in startup PollyHttpPolicies pollyHttpPolicies = new PollyHttpPolicies(new PollyHttpPoliciesConfig()); Dictionary <HttpClientConfigName, ApiConfig> httpClientConfigs = config.GetSection("Apis").Get <Dictionary <HttpClientConfigName, ApiConfig> >(); foreach (KeyValuePair <HttpClientConfigName, ApiConfig> httpClientConfig in httpClientConfigs) { IAsyncPolicy <HttpResponseMessage> retryPolicy = httpClientConfig.Value.IsExternal ? pollyHttpPolicies.ExternalHttpRetryPolicy : pollyHttpPolicies.InternalHttpRetryPolicy; builder.Services.AddHttpClient(httpClientConfig.Key.ToString(), c => { c.BaseAddress = new Uri(httpClientConfig.Value.BaseAddress); c.Timeout = httpClientConfig.Value.Timeout ?? new TimeSpan(0, 0, 0, 15); foreach (KeyValuePair <string, string> header in httpClientConfig.Value.Headers) { c.DefaultRequestHeaders.Add(header.Key, header.Value); } c.DefaultRequestHeaders.AcceptEncoding.Add(new StringWithQualityHeaderValue("gzip")); c.DefaultRequestHeaders.AcceptEncoding.Add(new StringWithQualityHeaderValue("deflate")); }).ConfigurePrimaryHttpMessageHandler(() => new HttpClientHandler { MaxConnectionsPerServer = httpClientConfig.Value.MaxConnectionsPerServer ?? int.MaxValue, AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate }).AddPolicyHandler(retryPolicy); } builder.Services.AddMediatR(typeof(GetUserByIDHandler).Assembly); IConfigurationSection connectionStringSettings = config.GetSection("ConnectionStrings"); builder.Services.Configure <ConnectionStrings>(connectionStringSettings); IConfigurationSection applicationConfigSettings = config.GetSection("ApplicationConfig"); builder.Services.Configure <ApplicationConfig>(applicationConfigSettings); var sqlConnectionString = config.GetConnectionString("SqlConnectionString"); builder.Services.AddDbContext <ApplicationDbContext>(options => options.UseSqlServer(sqlConnectionString)); builder.Services.AddTransient <IRepository, Repository>(); builder.Services.AddTransient <IAddressService, AddressService>(); builder.Services.AddTransient <ICommunicationService, CommunicationService>(); builder.Services.AddTransient <IGroupService, GroupService>(); builder.Services.AddTransient <IHelperService, HelperService>(); builder.Services.AddTransient <IHttpClientWrapper, HttpClientWrapper>(); builder.Services.AddTransient <IDistanceCalculator, DistanceCalculator>(); builder.Services.AddTransient <IVolunteerCache, VolunteerCache>(); builder.Services.AddTransient <IVolunteersForCacheGetter, VolunteersForCacheGetter>(); builder.Services.AddSingleton <IPollyMemoryCacheProvider, PollyMemoryCacheProvider>(); builder.Services.AddTransient <ISystemClock, MockableDateTime>(); builder.Services.AddTransient <ICoordinatedResetCache, CoordinatedResetCache>(); builder.Services.AddTransient <IVolunteersFilteredByMinDistanceGetter, VolunteersFilteredByMinDistanceGetter>(); builder.Services.AddTransient <IMinDistanceFilter, MinDistanceFilter>(); // add cache RedisConfig redisConfig = new RedisConfig(); config.GetSection("RedisConfig").Bind(redisConfig); builder.Services.AddMemDistCache(redisConfig.AppName, redisConfig.ConnectionString); builder.Services.AddSingleton <IMemDistCache <IEnumerable <CachedVolunteerDto> > >(x => x.GetService <IMemDistCacheFactory <IEnumerable <CachedVolunteerDto> > >().GetCache(new TimeSpan(7, 0, 0, 0), ResetTimeFactory.OnHour)); IConfigurationSection firebaseConfigSettings = config.GetSection("FirebaseConfig"); builder.Services.Configure <FirebaseConfig>(firebaseConfigSettings); builder.Services.AddSingleton <IAuthService, AuthService>(); // automatically apply EF migrations DbContextOptionsBuilder <ApplicationDbContext> dbContextOptionsBuilder = new DbContextOptionsBuilder <ApplicationDbContext>(); dbContextOptionsBuilder.UseSqlServer(sqlConnectionString); ApplicationDbContext dbContext = new ApplicationDbContext(dbContextOptionsBuilder.Options); dbContext.Database.Migrate(); }
public override void Configure(IFunctionsHostBuilder builder) { // We need to get the app directory this way. Using Environment.CurrentDirectory doesn't work in Azure ExecutionContextOptions executioncontextoptions = builder.Services.BuildServiceProvider() .GetService <IOptions <ExecutionContextOptions> >().Value; string currentDirectory = executioncontextoptions.AppDirectory; IConfigurationBuilder configBuilder = new ConfigurationBuilder() .SetBasePath(currentDirectory) .AddJsonFile("local.settings.json", optional: true, reloadOnChange: true) .AddEnvironmentVariables(); IConfigurationRoot config = configBuilder.Build(); // DI doesn't work in startup PollyHttpPolicies pollyHttpPolicies = new PollyHttpPolicies(new PollyHttpPoliciesConfig()); Dictionary <HttpClientConfigName, ApiConfig> httpClientConfigs = config.GetSection("Apis").Get <Dictionary <HttpClientConfigName, ApiConfig> >(); foreach (KeyValuePair <HttpClientConfigName, ApiConfig> httpClientConfig in httpClientConfigs) { IAsyncPolicy <HttpResponseMessage> retryPolicy = httpClientConfig.Value.IsExternal ? pollyHttpPolicies.ExternalHttpRetryPolicy : pollyHttpPolicies.InternalHttpRetryPolicy; builder.Services.AddHttpClient(httpClientConfig.Key.ToString(), c => { c.BaseAddress = new Uri(httpClientConfig.Value.BaseAddress); c.Timeout = httpClientConfig.Value.Timeout ?? new TimeSpan(0, 0, 0, 15); foreach (KeyValuePair <string, string> header in httpClientConfig.Value.Headers) { c.DefaultRequestHeaders.Add(header.Key, header.Value); } c.DefaultRequestHeaders.AcceptEncoding.Add(new StringWithQualityHeaderValue("gzip")); c.DefaultRequestHeaders.AcceptEncoding.Add(new StringWithQualityHeaderValue("deflate")); }).ConfigurePrimaryHttpMessageHandler(() => new HttpClientHandler { MaxConnectionsPerServer = httpClientConfig.Value.MaxConnectionsPerServer ?? 15, AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate }).AddPolicyHandler(retryPolicy); } IConfigurationSection emailConfigSettings = config.GetSection("EmailConfig"); builder.Services.Configure <EmailConfig>(emailConfigSettings); IConfigurationSection serviceBusConfigSettings = config.GetSection("ServiceBusConfig"); builder.Services.Configure <ServiceBusConfig>(serviceBusConfigSettings); ServiceBusConfig serviceBusConfig = serviceBusConfigSettings.Get <ServiceBusConfig>(); IConfigurationSection sendGridConfigSettings = config.GetSection("SendGridConfig"); builder.Services.Configure <SendGridConfig>(sendGridConfigSettings); var sendGridConfig = config.GetSection("SendGridConfig").Get <SendGridConfig>(); builder.Services.AddSingleton <ISendGridClient>(new SendGridClient(sendGridConfig.ApiKey)); builder.Services.AddTransient <IHttpClientWrapper, HttpClientWrapper>(); builder.Services.AddMediatR(typeof(SendEmailHandler).Assembly); builder.Services.AddAutoMapper(typeof(AddressDetailsProfile).Assembly); builder.Services.AddSingleton <IQueueClient>(new QueueClient(serviceBusConfig.ConnectionString, serviceBusConfig.MessageQueueName)); builder.Services.AddSingleton <IMessageFactory, MessageFactory>(); //builder.Services.AddSingleton<IConnectSendGridService, SendGridService>(); builder.Services.AddSingleton <ISendEmailService, SendEmailService>(); builder.Services.AddSingleton <IConnectUserService, ConnectUserService>(); builder.Services.AddSingleton <IConnectRequestService, ConnectRequestService>(); builder.Services.AddSingleton <IConnectGroupService, ConnectGroupService>(); builder.Services.AddTransient <IJobFilteringService, JobFilteringService>(); builder.Services.AddSingleton <IConnectAddressService, ConnectAddressService>(); builder.Services.AddSingleton <IConnectSendGridService, ConnectSendGridService>(); builder.Services.AddSingleton <IDistanceCalculator, DistanceCalculator>(); builder.Services.AddSingleton <IPurgeService, PurgeService>(); builder.Services.AddDbContext <ApplicationDbContext>(options => options.UseInMemoryDatabase(databaseName: "CommunicationService.AzureFunction")); builder.Services.AddTransient <IRepository, Repository>(); CosmosConfig cosmosConfig = config.GetSection("CosmosConfig").Get <CosmosConfig>(); builder.Services.AddSingleton <ICosmosDbService>(InitializeCosmosClientInstance(cosmosConfig)); InterUserMessageConfig interUserMessageConfig = config.GetSection("InterUserMessageConfig").Get <InterUserMessageConfig>(); builder.Services.AddSingleton <IInterUserMessageRepository>(InitializeCosmosClientInstance(interUserMessageConfig)); IConfigurationSection linkConfigSettings = config.GetSection("LinkConfig"); builder.Services.Configure <LinkConfig>(linkConfigSettings); LinkConfig linkConfig = config.GetSection("LinkConfig").Get <LinkConfig>(); builder.Services.AddSingleton <ILinkRepository>(InitializeCosmosClientInstance(linkConfig)); SendGridManagement.EmailTemplateUploader emailTemplateUploader = new SendGridManagement.EmailTemplateUploader(new SendGridClient(sendGridConfig.ApiKey), InitializeCosmosClientInstance(cosmosConfig)); builder.Services.AddSingleton <IPollyMemoryCacheProvider, PollyMemoryCacheProvider>(); builder.Services.AddMemCache(); builder.Services.AddSingleton(x => x.GetService <IMemDistCacheFactory <LocationDetails> >().GetCache(new TimeSpan(30, 0, 0, 0), ResetTimeFactory.OnMidday)); builder.Services.AddSingleton(x => x.GetService <IMemDistCacheFactory <Template> >().GetCache(new TimeSpan(30, 0, 0, 0), ResetTimeFactory.OnMidday)); builder.Services.AddSingleton(x => x.GetService <IMemDistCacheFactory <UnsubscribeGroup> >().GetCache(new TimeSpan(30, 0, 0, 0), ResetTimeFactory.OnMidday)); emailTemplateUploader.Migrate().ConfigureAwait(false); }
public override void Configure(IFunctionsHostBuilder builder) { // We need to get the app directory this way. Using Environment.CurrentDirectory doesn't work in Azure ExecutionContextOptions executioncontextoptions = builder.Services.BuildServiceProvider() .GetService <IOptions <ExecutionContextOptions> >().Value; string currentDirectory = executioncontextoptions.AppDirectory; IConfigurationBuilder configBuilder = new ConfigurationBuilder() .SetBasePath(currentDirectory) .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true) .AddUserSecrets(Assembly.GetExecutingAssembly(), true) .AddEnvironmentVariables(); IConfigurationRoot config = configBuilder.Build(); // DI doesn't work in startup PollyHttpPolicies pollyHttpPolicies = new PollyHttpPolicies(new PollyHttpPoliciesConfig()); Dictionary <HttpClientConfigName, ApiConfig> httpClientConfigs = config.GetSection("Apis").Get <Dictionary <HttpClientConfigName, ApiConfig> >(); foreach (KeyValuePair <HttpClientConfigName, ApiConfig> httpClientConfig in httpClientConfigs) { if (httpClientConfig.Key == HttpClientConfigName.Qas && !httpClientConfig.Value.Headers.ContainsKey("auth-token")) { throw new Exception("Qas requires auth-token header"); } IAsyncPolicy <HttpResponseMessage> retryPolicy = httpClientConfig.Value.IsExternal ? pollyHttpPolicies.ExternalHttpRetryPolicy : pollyHttpPolicies.InternalHttpRetryPolicy; builder.Services.AddHttpClient(httpClientConfig.Key.ToString(), c => { c.BaseAddress = new Uri(httpClientConfig.Value.BaseAddress); c.Timeout = httpClientConfig.Value.Timeout ?? new TimeSpan(0, 0, 0, 15); foreach (KeyValuePair <string, string> header in httpClientConfig.Value.Headers) { c.DefaultRequestHeaders.Add(header.Key, header.Value); } c.DefaultRequestHeaders.AcceptEncoding.Add(new StringWithQualityHeaderValue("gzip")); c.DefaultRequestHeaders.AcceptEncoding.Add(new StringWithQualityHeaderValue("deflate")); }).ConfigurePrimaryHttpMessageHandler(() => new HttpClientHandler { MaxConnectionsPerServer = httpClientConfig.Value.MaxConnectionsPerServer ?? 15, AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate }).AddPolicyHandler(retryPolicy); } builder.Services.TryAdd(ServiceDescriptor.Singleton(typeof(ILogger <>), typeof(Logger <>))); builder.Services.TryAdd(ServiceDescriptor.Singleton(typeof(ILoggerWrapper <>), typeof(LoggerWrapper <>))); builder.Services.AddTransient <IHttpClientWrapper, HttpClientWrapper>(); builder.Services.AddTransient <IQasMapper, QasMapper>(); builder.Services.AddTransient <IQasService, QasService>(); builder.Services.AddTransient <IPostcodeIoService, PostcodeIoService>(); builder.Services.AddTransient <IDistanceCalculator, DistanceCalculator>(); builder.Services.AddTransient <INearestPostcodeGetter, NearestPostcodeGetter>(); builder.Services.AddTransient <IQasAddressGetter, QasAddressGetter>(); builder.Services.AddTransient <IPostcodeAndAddressGetter, PostcodeAndAddressGetter>(); builder.Services.AddTransient <IPostcodeCoordinatesGetter, PostcodeCoordinatesGetter>(); builder.Services.AddSingleton <IPostcodesWithoutAddressesCache, PostcodesWithoutAddressesCache>(); builder.Services.AddTransient <IRegexPostcodeValidator, RegexPostcodeValidator>(); builder.Services.AddTransient <IPostcodeValidator, PostcodeValidator>(); builder.Services.AddTransient <IAddressDetailsSorter, AddressDetailsSorter>(); builder.Services.AddTransient <IFriendlyNameGenerator, FriendlyNameGenerator>(); builder.Services.AddMediatR(typeof(GetPostcodeHandler).Assembly); IEnumerable <Type> autoMapperProfiles = typeof(PostCodeProfile).Assembly.GetTypes().Where(x => typeof(Profile).IsAssignableFrom(x)).ToList(); foreach (var profile in autoMapperProfiles) { builder.Services.AddAutoMapper(profile.Assembly); } builder.Services.AddTransient <IRepository, Repository>(); IConfigurationSection applicationConfigSettings = config.GetSection("ApplicationConfig"); builder.Services.Configure <ApplicationConfig>(applicationConfigSettings); IConfigurationSection connectionStringSettings = config.GetSection("ConnectionStrings"); builder.Services.Configure <ConnectionStrings>(connectionStringSettings); ConnectionStrings connectionStrings = new ConnectionStrings(); connectionStringSettings.Bind(connectionStrings); builder.Services.AddDbContext <ApplicationDbContext>(options => ConfigureDbContextOptionsBuilder(options, connectionStrings.AddressService), ServiceLifetime.Transient ); // automatically apply EF migrations // DbContext is being created manually instead of through DI as it throws an exception and I've not managed to find a way to solve it yet: // 'Unable to resolve service for type 'Microsoft.Azure.WebJobs.Script.IFileLoggingStatusManager' while attempting to activate 'Microsoft.Azure.WebJobs.Script.Diagnostics.HostFileLoggerProvider'.' DbContextOptionsBuilder <ApplicationDbContext> dbContextOptionsBuilder = new DbContextOptionsBuilder <ApplicationDbContext>(); ConfigureDbContextOptionsBuilder(dbContextOptionsBuilder, connectionStrings.AddressService); ApplicationDbContext dbContext = new ApplicationDbContext(dbContextOptionsBuilder.Options); dbContext.Database.Migrate(); }
public override void Configure(IFunctionsHostBuilder builder) { ExecutionContextOptions executioncontextoptions = builder.Services.BuildServiceProvider() .GetService <IOptions <ExecutionContextOptions> >().Value; string currentDirectory = executioncontextoptions.AppDirectory; IConfigurationBuilder configBuilder = new ConfigurationBuilder() .SetBasePath(currentDirectory) .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true) .AddEnvironmentVariables(); IConfigurationRoot config = configBuilder.Build(); builder.Services.AddMediatR(typeof(PostCreateGroupHandler).Assembly); builder.Services.AddAutoMapper(typeof(UserRoleAuditProfile).Assembly); // DI doesn't work in startup PollyHttpPolicies pollyHttpPolicies = new PollyHttpPolicies(new PollyHttpPoliciesConfig()); Dictionary <HttpClientConfigName, ApiConfig> httpClientConfigs = config.GetSection("Apis").Get <Dictionary <HttpClientConfigName, ApiConfig> >(); foreach (KeyValuePair <HttpClientConfigName, ApiConfig> httpClientConfig in httpClientConfigs) { IAsyncPolicy <HttpResponseMessage> retryPolicy = httpClientConfig.Value.IsExternal ? pollyHttpPolicies.ExternalHttpRetryPolicy : pollyHttpPolicies.InternalHttpRetryPolicy; builder.Services.AddHttpClient(httpClientConfig.Key.ToString(), c => { c.BaseAddress = new Uri(httpClientConfig.Value.BaseAddress); c.Timeout = httpClientConfig.Value.Timeout ?? new TimeSpan(0, 0, 0, 15); foreach (KeyValuePair <string, string> header in httpClientConfig.Value.Headers) { c.DefaultRequestHeaders.Add(header.Key, header.Value); } c.DefaultRequestHeaders.AcceptEncoding.Add(new StringWithQualityHeaderValue("gzip")); c.DefaultRequestHeaders.AcceptEncoding.Add(new StringWithQualityHeaderValue("deflate")); }).ConfigurePrimaryHttpMessageHandler(() => new HttpClientHandler { MaxConnectionsPerServer = httpClientConfig.Value.MaxConnectionsPerServer ?? int.MaxValue, AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate }).AddPolicyHandler(retryPolicy); } IConfigurationSection applicationConfigSettings = config.GetSection("ApplicationConfig"); builder.Services.Configure <ApplicationConfig>(applicationConfigSettings); builder.Services.AddTransient <IHttpClientWrapper, HttpClientWrapper>(); builder.Services.AddTransient <IRepository, Repository>(); builder.Services.AddTransient <IUserService, Core.Services.UserService>(); builder.Services.AddTransient <IRequestService, Core.Services.RequestService>(); builder.Services.AddTransient <IExpiredService, Core.Services.ExpiredService>(); builder.Services.AddTransient <ICommunicationService, Core.Services.CommunicationService>(); builder.Services.TryAdd(ServiceDescriptor.Singleton(typeof(ILogger <>), typeof(Logger <>))); builder.Services.TryAdd(ServiceDescriptor.Singleton(typeof(ILoggerWrapper <>), typeof(LoggerWrapper <>))); IConfigurationSection connectionStringSettings = config.GetSection("ConnectionStrings"); builder.Services.Configure <ConnectionStrings>(connectionStringSettings); ConnectionStrings connectionStrings = new ConnectionStrings(); connectionStringSettings.Bind(connectionStrings); builder.Services.AddDbContext <ApplicationDbContext>(options => ConfigureDbContextOptionsBuilder(options, connectionStrings.GroupService), ServiceLifetime.Transient ); // automatically apply EF migrations // DbContext is being created manually instead of through DI as it throws an exception and I've not managed to find a way to solve it yet: // 'Unable to resolve service for type 'Microsoft.Azure.WebJobs.Script.IFileLoggingStatusManager' while attempting to activate 'Microsoft.Azure.WebJobs.Script.Diagnostics.HostFileLoggerProvider'.' DbContextOptionsBuilder <ApplicationDbContext> dbContextOptionsBuilder = new DbContextOptionsBuilder <ApplicationDbContext>(); ConfigureDbContextOptionsBuilder(dbContextOptionsBuilder, connectionStrings.GroupService); ApplicationDbContext dbContext = new ApplicationDbContext(dbContextOptionsBuilder.Options); dbContext.Database.Migrate(); }
// This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme) .AddCookie(options => { options.Cookie.HttpOnly = true; options.Cookie.SecurePolicy = CookieSecurePolicy.Always; options.Cookie.SameSite = SameSiteMode.Strict; options.LoginPath = "/login"; }); services.AddControllersWithViews(); services.Configure <YotiOptions>(Configuration.GetSection("Yoti")); services.Configure <EmailConfig>(Configuration.GetSection("EmailConfig")); PollyHttpPolicies pollyHttpPolicies = new PollyHttpPolicies(new PollyHttpPoliciesConfig()); services.AddHttpClient <IUserRepository, UserRepository>(client => { client.DefaultRequestHeaders.AcceptEncoding.Add(new StringWithQualityHeaderValue("gzip")); client.DefaultRequestHeaders.AcceptEncoding.Add(new StringWithQualityHeaderValue("deflate")); }).ConfigurePrimaryHttpMessageHandler(() => new HttpClientHandler { AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate }).AddPolicyHandler(pollyHttpPolicies.InternalHttpRetryPolicy); services.AddHttpClient <IVerificationRepository, VerificationRepository>(client => { client.DefaultRequestHeaders.AcceptEncoding.Add(new StringWithQualityHeaderValue("gzip")); client.DefaultRequestHeaders.AcceptEncoding.Add(new StringWithQualityHeaderValue("deflate")); }).ConfigurePrimaryHttpMessageHandler(() => new HttpClientHandler { AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate }).AddPolicyHandler(pollyHttpPolicies.InternalHttpRetryPolicy); services.AddHttpClient <IAddressRepository, AddressRepository>(client => { client.DefaultRequestHeaders.AcceptEncoding.Add(new StringWithQualityHeaderValue("gzip")); client.DefaultRequestHeaders.AcceptEncoding.Add(new StringWithQualityHeaderValue("deflate")); }).ConfigurePrimaryHttpMessageHandler(() => new HttpClientHandler { AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate }).AddPolicyHandler(pollyHttpPolicies.InternalHttpRetryPolicy); services.AddHttpClient <IRequestHelpRepository, RequestHelpRepository>(client => { client.DefaultRequestHeaders.AcceptEncoding.Add(new StringWithQualityHeaderValue("gzip")); client.DefaultRequestHeaders.AcceptEncoding.Add(new StringWithQualityHeaderValue("deflate")); }).ConfigurePrimaryHttpMessageHandler(() => new HttpClientHandler { AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate }).AddPolicyHandler(pollyHttpPolicies.InternalHttpRetryPolicy); services.AddHttpClient <IAddressService, AddressService>(client => { client.DefaultRequestHeaders.AcceptEncoding.Add(new StringWithQualityHeaderValue("gzip")); client.DefaultRequestHeaders.AcceptEncoding.Add(new StringWithQualityHeaderValue("deflate")); }).ConfigurePrimaryHttpMessageHandler(() => new HttpClientHandler { AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate }).AddPolicyHandler(pollyHttpPolicies.InternalHttpRetryPolicy); services.AddHttpClient <IVerificationService, VerificationService>(client => { client.DefaultRequestHeaders.AcceptEncoding.Add(new StringWithQualityHeaderValue("gzip")); client.DefaultRequestHeaders.AcceptEncoding.Add(new StringWithQualityHeaderValue("deflate")); }).ConfigurePrimaryHttpMessageHandler(() => new HttpClientHandler { AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate }).AddPolicyHandler(pollyHttpPolicies.InternalHttpRetryPolicy); services.AddHttpClient <IGoogleService, GoogleService>(client => { client.DefaultRequestHeaders.AcceptEncoding.Add(new StringWithQualityHeaderValue("gzip")); client.DefaultRequestHeaders.AcceptEncoding.Add(new StringWithQualityHeaderValue("deflate")); }).ConfigurePrimaryHttpMessageHandler(() => new HttpClientHandler { AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate }); services.AddHttpClient <IGroupRepository, GroupRepository>(client => { client.DefaultRequestHeaders.AcceptEncoding.Add(new StringWithQualityHeaderValue("gzip")); client.DefaultRequestHeaders.AcceptEncoding.Add(new StringWithQualityHeaderValue("deflate")); }).ConfigurePrimaryHttpMessageHandler(() => new HttpClientHandler { AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate }); services.AddHttpClient <ICommunicationService, CommunicationService>(client => { client.DefaultRequestHeaders.AcceptEncoding.Add(new StringWithQualityHeaderValue("gzip")); client.DefaultRequestHeaders.AcceptEncoding.Add(new StringWithQualityHeaderValue("deflate")); }).ConfigurePrimaryHttpMessageHandler(() => new HttpClientHandler { AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate }); services.AddHttpClient <IFeedbackRepository, FeedbackRepository>(client => { client.DefaultRequestHeaders.AcceptEncoding.Add(new StringWithQualityHeaderValue("gzip")); client.DefaultRequestHeaders.AcceptEncoding.Add(new StringWithQualityHeaderValue("deflate")); }).ConfigurePrimaryHttpMessageHandler(() => new HttpClientHandler { AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate }); services.AddSingleton <ICommunityRepository, CommunityRepository>(); services.AddSingleton <IAwardsRepository, AwardsRepository>(); services.AddSingleton <IUserService, HelpMyStreetFE.Services.Users.UserService>(); services.AddSingleton <IAwardsRepository, AwardsRepository>(); services.AddSingleton <IAuthService, AuthService>(); services.AddSingleton <IRequestHelpBuilder, RequestHelpBuilder>(); services.AddDistributedMemoryCache(); // Adds a default in-memory implementation of IDistributedCache services.AddSession(); services.AddSingleton <IRequestService, RequestService>(); services.AddSingleton <IGroupService, GroupService>(); services.AddSingleton <IGroupMemberService, GroupMemberService>(); services.AddSingleton <IFilterService, FilterService>(); services.AddSingleton <IFeedbackService, FeedbackService>(); // cache services.AddSingleton <IPollyMemoryCacheProvider, PollyMemoryCacheProvider>(); services.AddTransient <ISystemClock, MockableDateTime>(); services.AddSingleton <ICoordinatedResetCache, CoordinatedResetCache>(); services.AddMemCache(); services.AddSingleton(x => x.GetService <IMemDistCacheFactory <IEnumerable <JobSummary> > >().GetCache(new TimeSpan(1, 0, 0), ResetTimeFactory.OnMinute)); services.AddSingleton(x => x.GetService <IMemDistCacheFactory <IEnumerable <ShiftJob> > >().GetCache(new TimeSpan(1, 0, 0), ResetTimeFactory.OnMinute)); services.AddSingleton(x => x.GetService <IMemDistCacheFactory <IEnumerable <RequestSummary> > >().GetCache(new TimeSpan(1, 0, 0), ResetTimeFactory.OnMinute)); services.AddSingleton(x => x.GetService <IMemDistCacheFactory <List <UserGroup> > >().GetCache(new TimeSpan(1, 0, 0), ResetTimeFactory.OnMinute)); services.AddSingleton(x => x.GetService <IMemDistCacheFactory <int> >().GetCache(new TimeSpan(30, 0, 0, 0), ResetTimeFactory.OnMidday)); services.AddSingleton(x => x.GetService <IMemDistCacheFactory <User> >().GetCache(new TimeSpan(2, 0, 0), ResetTimeFactory.OnHour)); services.AddSingleton(x => x.GetService <IMemDistCacheFactory <Group> >().GetCache(new TimeSpan(30, 0, 0, 0), ResetTimeFactory.OnHour)); services.AddSingleton(x => x.GetService <IMemDistCacheFactory <List <Group> > >().GetCache(new TimeSpan(30, 0, 0, 0), ResetTimeFactory.OnHour)); services.AddSingleton(x => x.GetService <IMemDistCacheFactory <List <List <GroupCredential> > > >().GetCache(new TimeSpan(30, 0, 0, 0), ResetTimeFactory.OnHour)); services.AddSingleton(x => x.GetService <IMemDistCacheFactory <UserInGroup> >().GetCache(new TimeSpan(1, 0, 0), ResetTimeFactory.OnMinute)); services.AddSingleton(x => x.GetService <IMemDistCacheFactory <Instructions> >().GetCache(new TimeSpan(30, 0, 0, 0), ResetTimeFactory.OnHour)); services.AddSingleton(x => x.GetService <IMemDistCacheFactory <LocationDetails> >().GetCache(new TimeSpan(30, 0, 0, 0), ResetTimeFactory.OnMidday)); services.AddSingleton(x => x.GetService <IMemDistCacheFactory <IEnumerable <LocationDetails> > >().GetCache(new TimeSpan(30, 0, 0, 0), ResetTimeFactory.OnMidday)); services.AddSingleton(x => x.GetService <IMemDistCacheFactory <IEnumerable <LocationWithDistance> > >().GetCache(new TimeSpan(30, 0, 0, 0), ResetTimeFactory.OnMidday)); services.AddSingleton(x => x.GetService <IMemDistCacheFactory <double> >().GetCache(new TimeSpan(30, 0, 0, 0), ResetTimeFactory.OnMidday)); services.AddSingleton(x => x.GetService <IMemDistCacheFactory <IEnumerable <LocationWithDistance> > >().GetCache(new TimeSpan(30, 0, 0, 0), ResetTimeFactory.OnMinute)); services.AddControllers(); services.AddRazorPages() .AddRazorRuntimeCompilation() .AddRazorOptions(opt => { opt.ViewLocationFormats.Add("/Views/Account/Verification/{0}.cshtml"); opt.ViewLocationFormats.Add("/Views/Community/{0}.cshtml"); opt.ViewLocationFormats.Add("/Views/RequestHelp/RequestStage/{0}.cshtml"); opt.ViewLocationFormats.Add("/Views/RequestHelp/DetailStage/{0}.cshtml"); opt.ViewLocationFormats.Add("/Views/RequestHelp/ReviewStage/{0}.cshtml"); opt.ViewLocationFormats.Add("/Views/Shared/Components/FeedbackCapture/{0}.cshtml"); opt.ViewLocationFormats.Add("/Views/Shared/Components/Notifications/{0}.cshtml"); opt.ViewLocationFormats.Add("/Views/Shared/DisplayTemplates/{0}.cshtml"); }); }