using Ardalis.ListStartupServices; using MediatR; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Diagnostics.HealthChecks; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Mvc.ApplicationModels; using Microsoft.EntityFrameworkCore; using Microsoft.eShopWeb.ApplicationCore.Interfaces; using Microsoft.eShopWeb.ApplicationCore.Services; using Microsoft.eShopWeb.Infrastructure.Data; using Microsoft.eShopWeb.Infrastructure.Identity; using Microsoft.eShopWeb.Infrastructure.Logging; using Microsoft.eShopWeb.Infrastructure.Services; using Microsoft.eShopWeb.Web.API; using Microsoft.eShopWeb.Web.Interfaces; using Microsoft.eShopWeb.Web.Services; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Diagnostics.HealthChecks; using Microsoft.Extensions.Hosting; using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Linq; using System.Net.Mime; using static Microsoft.eShopWeb.Web.API.BaseRequest; namespace Microsoft.eShopWeb.Web { public class Startup { private IServiceCollection _services; public Startup(IConfiguration configuration) { Configuration = configuration; } public IConfiguration Configuration { get; } public void ConfigureDevelopmentServices(IServiceCollection services) { // use in-memory database ConfigureInMemoryDatabases(services); // use real database //ConfigureProductionServices(services); } private void ConfigureInMemoryDatabases(IServiceCollection services) { // use in-memory database services.AddDbContext(c => c.UseInMemoryDatabase("Catalog")); // Add Identity DbContext services.AddDbContext(options => options.UseInMemoryDatabase("Identity")); ConfigureServices(services); } public void ConfigureProductionServices(IServiceCollection services) { // use real database // Requires LocalDB which can be installed with SQL Server Express 2016 // https://www.microsoft.com/en-us/download/details.aspx?id=54284 services.AddDbContext(c => c.UseSqlServer(Configuration.GetConnectionString("CatalogConnection"))); // Add Identity DbContext services.AddDbContext(options => options.UseSqlServer(Configuration.GetConnectionString("IdentityConnection"))); ConfigureServices(services); } public void ConfigureTestingServices(IServiceCollection services) { ConfigureInMemoryDatabases(services); } // This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { ConfigureCookieSettings(services); services.AddIdentity() .AddDefaultUI() .AddEntityFrameworkStores() .AddDefaultTokenProviders(); services.AddMediatR(typeof(BasketViewModelService).Assembly); services.AddScoped(typeof(IAsyncRepository<>), typeof(EfRepository<>)); services.AddScoped(); services.AddScoped(); services.AddScoped(); services.AddScoped(); services.AddScoped(); services.AddScoped(); services.AddScoped(); services.Configure(Configuration); services.AddSingleton(new UriComposer(Configuration.Get())); services.AddScoped(typeof(IAppLogger<>), typeof(LoggerAdapter<>)); services.AddTransient(); // Add memory cache services services.AddMemoryCache(); services.AddRouting(options => { // Replace the type and the name used to refer to it with your own // IOutboundParameterTransformer implementation options.ConstraintMap["slugify"] = typeof(SlugifyParameterTransformer); }); services.AddMvc(options => { options.Conventions.Add(new RouteTokenTransformerConvention( new SlugifyParameterTransformer())); }); services.AddRazorPages(options => { options.Conventions.AuthorizePage("/Basket/Checkout"); }); services.AddControllersWithViews(); services.AddHttpContextAccessor(); services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new OpenApi.Models.OpenApiInfo { Title = "My API", Version = "v1" }); c.EnableAnnotations(); c.SchemaFilter(); }); services.AddHealthChecks(); services.Configure(config => { config.Services = new List(services); config.Path = "/allservices"; }); _services = services; // used to debug registered services } private static void ConfigureCookieSettings(IServiceCollection services) { services.Configure(options => { // This lambda determines whether user consent for non-essential cookies is needed for a given request. options.CheckConsentNeeded = context => true; options.MinimumSameSitePolicy = SameSiteMode.None; }); services.ConfigureApplicationCookie(options => { options.Cookie.HttpOnly = true; options.ExpireTimeSpan = TimeSpan.FromHours(1); options.LoginPath = "/Account/Login"; options.LogoutPath = "/Account/Logout"; options.Cookie = new CookieBuilder { IsEssential = true // required for auth to work without explicit user consent; adjust to suit your privacy policy }; }); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { app.UseHealthChecks("/health", new HealthCheckOptions { ResponseWriter = async (context, report) => { var result = new { status = report.Status.ToString(), errors = report.Entries.Select(e => new { key = e.Key, value = Enum.GetName(typeof(HealthStatus), e.Value.Status) }) }.ToJson(); context.Response.ContentType = MediaTypeNames.Application.Json; await context.Response.WriteAsync(result); } }); if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); app.UseShowAllServicesMiddleware(); app.UseDatabaseErrorPage(); } else { app.UseExceptionHandler("/Error"); // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. app.UseHsts(); } app.UseStaticFiles(); app.UseRouting(); app.UseHttpsRedirection(); app.UseCookiePolicy(); app.UseAuthentication(); app.UseAuthorization(); // Enable middleware to serve generated Swagger as a JSON endpoint. app.UseSwagger(); // Enable middleware to serve swagger-ui (HTML, JS, CSS, etc.), // specifying the Swagger JSON endpoint. app.UseSwaggerUI(c => { c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1"); }); app.UseEndpoints(endpoints => { endpoints.MapControllerRoute("default", "{controller:slugify=Home}/{action:slugify=Index}/{id?}"); endpoints.MapRazorPages(); endpoints.MapHealthChecks("home_page_health_check"); endpoints.MapHealthChecks("api_health_check"); }); } } }