// This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { services.AddThreaxProgressiveWebApp(o => Configuration.Bind("DisplayConfig", o)); //Add the client side configuration object services.AddClientConfig(clientConfig, o => { o.RouteArgsToClear = new List <string>() { "inPagePath" }; }); services.AddAssetBundle(o => { o.UseBundles = appConfig.UseAssetBundles; }); ApiExplorerController.Allow = appConfig.AllowApiExplorer; services.AddTimeTracking(); services.AddHalClientGen(new HalClientGenOptions() { SourceAssemblies = new Assembly[] { this.GetType().GetTypeInfo().Assembly, typeof(UserSearchController).Assembly }, CSharp = new CSharpOptions() { Namespace = "AppTemplate.Client" } }); services.AddConventionalIdServerAuthentication(o => { o.AppOptions = authConfig; o.CookiePath = appConfig.PathBase; o.AccessDeniedPath = "/Account/AccessDenied"; o.EnableIdServerMetadata = appConfig.EnableIdServerMetadata; }); services.AddAppDatabase(appConfig.ConnectionString); services.AddAppMapper(); services.AddAppRepositories(); var halOptions = new HalcyonConventionOptions() { BaseUrl = appConfig.BaseUrl, HalDocEndpointInfo = new HalDocEndpointInfo(typeof(EndpointDocController), appConfig.CacheToken), EnableValueProviders = appConfig.EnableValueProviders }; services.AddConventionalHalcyon(halOptions); services.AddHalcyonClient(); services.AddExceptionErrorFilters(new ExceptionFilterOptions() { DetailedErrors = appConfig.DetailedErrors }); services.AddThreaxIdServerClient(o => { Configuration.Bind("IdServerClient", o); }) .SetupHttpClientFactoryWithClientCredentials(o => { Configuration.Bind("IdServerClient", o); o.GetSharedClientCredentials = s => Configuration.Bind("SharedClientCredentials", s); }); // Add framework services. services.AddMvc(o => { o.UseExceptionErrorFilters(); o.UseConventionalHalcyon(halOptions); }) .AddNewtonsoftJson(o => { o.SerializerSettings.SetToHalcyonDefault(); o.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore; }) .AddRazorRuntimeCompilation() .AddConventionalIdServerMvc() .AddThreaxUserLookup(o => { o.UseIdServer(); }) .AddThreaxCacheUi(appConfig.CacheToken, o => { o.CacheControlHeader = appConfig.CacheControlHeaderString; }); services.ConfigureHtmlRapierTagHelpers(o => { o.FrontEndLibrary = HtmlRapier.TagHelpers.FrontEndLibrary.Bootstrap4; }); services.AddScoped <IToolRunner>(s => { var runner = new ToolRunner() .AddTool("migrate", new ToolCommand("Migrate database to newest version. Run anytime new migrations have been added.", async a => { await a.Migrate(); })) .AddTool("seed", new ToolCommand("Seed database data. Only needed for an empty database.", async a => { await a.Seed(); })) .AddTool("addadmin", new ToolCommand("Add given guids as a user with permissions to all roles in the database.", async a => { await a.AddAdmin(); })); #if DEBUG runner.AddTool("updateConfigSchema", new ToolCommand("Update the schema file for this application's configuration.", async a => { var json = await Configuration.CreateSchema(); await File.WriteAllTextAsync("appsettings.schema.json", json); })) .AddTool("createModel", new ToolCommand("Create a model from a model schema using Threax.ModelGen.", a => Threax.ModelGen.ModelGenerator.RunGenerate(a.Args[0]))) .AddTool("deleteModel", new ToolCommand("Delete a model from a model schema using Threax.ModelGen.", a => Threax.ModelGen.ModelGenerator.RunDelete(a.Args[0]))) .UseClientGenTools(); #endif return(runner); }); services.AddUserBuilderForUserWhitelistWithRoles(); services.AddThreaxCSP(o => { o.AddDefault().AddNone(); o.AddImg().AddSelf().AddData(); o.AddConnect().AddSelf(); o.AddManifest().AddSelf(); o.AddFont().AddSelf(); o.AddFrame().AddSelf().AddEntries(new String[] { authConfig.Authority }); o.AddScript().AddSelf().AddNonce(); o.AddStyle().AddSelf().AddNonce(); o.AddFrameAncestors().AddSelf(); }); services.AddLogging(o => { o.AddConfiguration(Configuration.GetSection("Logging")) .AddConsole() .AddDebug(); }); services.AddEntryPointRenderer <EntryPointController>(e => e.Get()); services.AddSingleton <AppConfig>(appConfig); if (appConfig.EnableResponseCompression) { services.AddResponseCompression(); } IdentityModelEventSource.ShowPII = appConfig.ShowPII; }