public void ConfigureServices(IServiceCollection services) { // Add services required for using options services.AddOptions(); // Configure ExchangeratesApiOptions var exchangeratesApiOptions = Configuration.GetSection(nameof(ExchangeratesApiOptions)); services.Configure <ExchangeratesApiOptions>(options => { options.HandlerLifetimeMinutes = Convert.ToInt32(exchangeratesApiOptions[nameof(ExchangeratesApiOptions.HandlerLifetimeMinutes)]); options.Url = exchangeratesApiOptions[nameof(ExchangeratesApiOptions.Url)]; options.AccessKey = exchangeratesApiOptions[nameof(ExchangeratesApiOptions.AccessKey)]; }); // Configure MassTransitOptions var massTransitOptions = Configuration.GetSection(nameof(MassTransitOptions)); services.Configure <MassTransitOptions>(options => { options.Host = massTransitOptions[nameof(MassTransitOptions.Host)]; options.Username = massTransitOptions[nameof(MassTransitOptions.Username)]; options.Password = massTransitOptions[nameof(MassTransitOptions.Password)]; options.QueueName = massTransitOptions[nameof(MassTransitOptions.QueueName)]; options.ReceiveEndpointPrefetchCount = Convert.ToInt32(massTransitOptions[nameof(MassTransitOptions.ReceiveEndpointPrefetchCount)]); }); // Configure HealthChecksOptions var healthChecksOptions = Configuration.GetSection(nameof(HealthChecksOptions)); services.Configure <HealthChecksOptions>(options => { options.PrivateMemoryName = healthChecksOptions[nameof(HealthChecksOptions.PrivateMemoryName)]; options.PrivateMemoryMax = Convert.ToInt32(healthChecksOptions[nameof(HealthChecksOptions.PrivateMemoryMax)]); options.ProcessAllocatedMemoryName = healthChecksOptions[nameof(HealthChecksOptions.ProcessAllocatedMemoryName)]; options.ProcessAllocatedMemoryMax = Convert.ToInt32(healthChecksOptions[nameof(HealthChecksOptions.ProcessAllocatedMemoryMax)]); }); // Configure DI for application services RegisterServices(services); // https://asp.net-hacker.rocks/2020/08/20/health-checks.html services.AddHealthChecks() .AddPrivateMemoryHealthCheck(Convert.ToInt32(healthChecksOptions[nameof(HealthChecksOptions.PrivateMemoryMax)]), healthChecksOptions[nameof(HealthChecksOptions.PrivateMemoryName)]) .AddProcessAllocatedMemoryHealthCheck(Convert.ToInt32(healthChecksOptions[nameof(HealthChecksOptions.ProcessAllocatedMemoryMax)]), healthChecksOptions[nameof(HealthChecksOptions.ProcessAllocatedMemoryName)]) .AddUrlGroup(sp => { var options = sp.GetRequiredService <IOptions <ExchangeratesApiOptions> >().Value; return(new Uri(options.Url)); }, name: exchangeratesApiOptions[nameof(ExchangeratesApiOptions.Name)], failureStatus: HealthStatus.Degraded); // https://localhost:{port}/healthchecks-ui services.AddHealthChecksUI(opt => { opt.SetEvaluationTimeInSeconds(15); // time in seconds between check opt.MaximumHistoryEntriesPerEndpoint(60); // maximum history of checks opt.SetApiMaxActiveRequests(1); // api requests concurrency }) .AddInMemoryStorage(); var handlerLifetimeMinutes = Convert.ToInt32(exchangeratesApiOptions[nameof(ExchangeratesApiOptions.HandlerLifetimeMinutes)]); services.AddHttpClient <IEcbExchangeRatesApi, EcbExchangeRatesApi>() .AddPolicyHandler(RetryPolicies.GetRetryPolicy()) .ConfigurePrimaryHttpMessageHandler(() => new HttpClientHandler() { ClientCertificateOptions = ClientCertificateOption.Manual, ServerCertificateCustomValidationCallback = (httpRequestMessage, cert, cetChain, policyErrors) => { return(true); } }) .SetHandlerLifetime(TimeSpan.FromMinutes(handlerLifetimeMinutes)); // Formats the endpoint names usink kebab-case (dashed snake case) services.TryAddSingleton(KebabCaseEndpointNameFormatter.Instance); // Add MassTransit support services.AddMassTransit(x => { // Automatically discover Consumers x.AddConsumers(Assembly.GetExecutingAssembly()); x.AddBus(provider => Bus.Factory.CreateUsingRabbitMq(cfg => { cfg.Host(new Uri(massTransitOptions[nameof(MassTransitOptions.Host)]), h => { h.Username(massTransitOptions[nameof(MassTransitOptions.Username)]); h.Password(massTransitOptions[nameof(MassTransitOptions.Password)]); }); //cfg.ReceiveEndpoint("test", ecfg => cfg.ReceiveEndpoint(massTransitOptions[nameof(MassTransitOptions.QueueName)], ecfg => { ecfg.PrefetchCount = Convert.ToInt16(massTransitOptions[nameof(MassTransitOptions.ReceiveEndpointPrefetchCount)]); ecfg.ConfigureConsumers(provider); ecfg.UseMessageRetry(r => r.Interval(5, 1000)); ecfg.UseJsonSerializer(); }); })); }); services.AddMassTransitHostedService(); services.AddCors(); services.AddRouting(options => options.LowercaseUrls = true); }
public void ConfigureServices(IServiceCollection services) { // Add services required for using options services.AddOptions(); // Configure CoinCapAssetsApiOptions var exchangeratesApiOptions = Configuration.GetSection(nameof(CoinCapAssetsApiOptions)); services.Configure <CoinCapAssetsApiOptions>(options => { options.HandlerLifetimeMinutes = Convert.ToInt32(exchangeratesApiOptions[nameof(CoinCapAssetsApiOptions.HandlerLifetimeMinutes)]); options.Url = exchangeratesApiOptions[nameof(CoinCapAssetsApiOptions.Url)]; }); // Configure MassTransitOptions var massTransitOptions = Configuration.GetSection(nameof(MassTransitOptions)); services.Configure <MassTransitOptions>(options => { options.Host = massTransitOptions[nameof(MassTransitOptions.Host)]; options.Username = massTransitOptions[nameof(MassTransitOptions.Username)]; options.Password = massTransitOptions[nameof(MassTransitOptions.Password)]; options.ReceiveEndpointName = massTransitOptions[nameof(MassTransitOptions.ReceiveEndpointName)]; options.ReceiveEndpointPrefetchCount = Convert.ToInt32(massTransitOptions[nameof(MassTransitOptions.ReceiveEndpointPrefetchCount)]); }); // Configure HealthChecksOptions var healthChecksOptions = Configuration.GetSection(nameof(HealthChecksOptions)); services.Configure <HealthChecksOptions>(options => { options.PrivateMemoryName = healthChecksOptions[nameof(HealthChecksOptions.PrivateMemoryName)]; options.PrivateMemoryMax = Convert.ToInt32(healthChecksOptions[nameof(HealthChecksOptions.PrivateMemoryMax)]); options.ProcessAllocatedMemoryName = healthChecksOptions[nameof(HealthChecksOptions.ProcessAllocatedMemoryName)]; options.ProcessAllocatedMemoryMax = Convert.ToInt32(healthChecksOptions[nameof(HealthChecksOptions.ProcessAllocatedMemoryMax)]); }); // Configure DI for application services RegisterServices(services); // https://asp.net-hacker.rocks/2020/08/20/health-checks.html services.AddHealthChecks() .AddPrivateMemoryHealthCheck(Convert.ToInt32(healthChecksOptions[nameof(HealthChecksOptions.PrivateMemoryMax)]), healthChecksOptions[nameof(HealthChecksOptions.PrivateMemoryName)]) .AddProcessAllocatedMemoryHealthCheck(Convert.ToInt32(healthChecksOptions[nameof(HealthChecksOptions.ProcessAllocatedMemoryMax)]), healthChecksOptions[nameof(HealthChecksOptions.ProcessAllocatedMemoryName)]) .AddUrlGroup(sp => { var options = sp.GetRequiredService <IOptions <CoinCapAssetsApiOptions> >().Value; return(new Uri(options.Url)); }, name: exchangeratesApiOptions[nameof(CoinCapAssetsApiOptions.Name)], failureStatus: HealthStatus.Degraded); //services.AddHealthChecksUI(settings => settings // .AddHealthCheckEndpoint($"{SERVICE_NAME} Health Checks", "https://localhost:7001/health")) // .AddInMemoryStorage(); services.AddHealthChecksUI() .AddInMemoryStorage(); var handlerLifetimeMinutes = Convert.ToInt32(exchangeratesApiOptions[nameof(CoinCapAssetsApiOptions.HandlerLifetimeMinutes)]); services.AddHttpClient <ICoinCapAssetsApi, CoinCapAssetsApi>() .AddPolicyHandler(RetryPolicies.GetRetryPolicy()) .ConfigurePrimaryHttpMessageHandler(() => new HttpClientHandler() { ClientCertificateOptions = ClientCertificateOption.Manual, ServerCertificateCustomValidationCallback = (httpRequestMessage, cert, cetChain, policyErrors) => { return(true); } }) .SetHandlerLifetime(TimeSpan.FromMinutes(handlerLifetimeMinutes)); // Formats the endpoint names usink kebab-case (dashed snake case) services.TryAddSingleton(KebabCaseEndpointNameFormatter.Instance); // Add MassTransit support services.AddMassTransit(config => { // Automatically discover Consumers config.AddConsumers(Assembly.GetExecutingAssembly()); // Add Service Bus config.AddBus(provider => Bus.Factory.CreateUsingRabbitMq(cfg => { cfg.UseHealthCheck(provider); cfg.Host(new Uri(massTransitOptions[nameof(MassTransitOptions.Host)]), hcfg => { hcfg.Username(massTransitOptions[nameof(MassTransitOptions.Username)]); hcfg.Password(massTransitOptions[nameof(MassTransitOptions.Password)]); }); cfg.ReceiveEndpoint(massTransitOptions[nameof(MassTransitOptions.ReceiveEndpointName)], ecfg => { ecfg.PrefetchCount = Convert.ToUInt16(massTransitOptions[nameof(MassTransitOptions.ReceiveEndpointPrefetchCount)]); ecfg.ConfigureConsumers(provider); ecfg.UseMessageRetry(r => r.Interval(5, 1000)); ecfg.UseJsonSerializer(); }); })); }); services.AddMassTransitHostedService(); services.AddCors(); services.AddRouting(options => options.LowercaseUrls = true); }