public GetQuoteCommand(HttpClient httpClient, IOptions <FunnyQuotesConfiguration> config, IHttpContextAccessor httpContextAccessor, ILogger <GetQuoteCommand> logger) : base(_options) { _httpClient = httpClient; _config = config.Value; _httpContextAccessor = httpContextAccessor; _logger = logger; }
// This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { // while we're registering FunnyQuotesConfiguration as part of .Configure call, we need that data now // as we're making registration decisions. We manually gonna create an instance and map it on to config var funnyquotesConfig = new FunnyQuotesConfiguration(); Configuration.GetSection("FunnyQuotes").Bind(funnyquotesConfig); ((IConfigurationRoot)Configuration).AutoRefresh(TimeSpan.FromSeconds(10)); // start a background timer thread to update config every 10 seconds // alternatively can do the same thing by POSTing to /refresh endpoint services.AddMvc(); services.AddCloudFoundryActuators(Configuration); // enable all actuators on /cloudfoundryapplication endpoint that integrate with CF with enabled security services.AddDiscoveryClient(Configuration); // register eureka (service discovery) with container. Can inject IDiscoveryClient services.AddDistributedTracing(Configuration, builder => builder.UseZipkinWithTraceOptions(services)); // services.AddTransient <DiscoveryHttpMessageHandler>(); // used for HttpClientFactory services.TryAddSingleton <IHttpContextAccessor, HttpContextAccessor>(); // .net core way of accessing current http context (legacy HttpContext.Current) services.AddLogging(); // can inject ILogger<T> services.AddSingleton <LocalFunnyQuoteService>(); services.AddScoped <RestFunnyQuotesClient>(); services.AddScoped <WcfFunnyQuotesClient>(); services.AddOptions(); services.Configure <FunnyQuotesConfiguration>(Configuration.GetSection("FunnyQuotes")); // adds typed configuration object and map it to a section of config services.AddHystrixCommand <RestFunnyQuotesClient.GetQuoteCommand>("Core.RandomQuote", "Core.RandomQuote", Configuration); // register injectable hystrix command services.AddTransient <IFunnyQuoteService>(provider => { // the concrete implementation of IFunnyQuoteService is based on what's configured in config provider // this can change at runtime if config value changes var config = provider.GetService <IOptionsSnapshot <FunnyQuotesConfiguration> >(); var implType = config.Value.ClientType; if (implType == "rest") { return(provider.GetService <RestFunnyQuotesClient>()); } if (implType == "wcf") { return(provider.GetService <WcfFunnyQuotesClient>()); } return(provider.GetService <LocalFunnyQuoteService>()); }); services.AddHttpClient <RestFunnyQuotesClient.GetQuoteCommand>(client => { client.BaseAddress = new Uri("http://FunnyQuotesServicesOwin/api/FunnyQuotes/"); }).AddHttpMessageHandler <DiscoveryHttpMessageHandler>(); // use eureka integration with all HttpClient objects services.AddSingleton <IAuthenticationSchemeProvider, FeatureToggleAuthenticationSchemeProvider>(); // add OAuth2 sign in scheme var authBuilder = services .AddAuthentication(options => { options.DefaultScheme = CloudFoundryDefaults.AuthenticationScheme; options.DefaultChallengeScheme = CloudFoundryDefaults.AuthenticationScheme; }) .AddCookie((options) => { options.AccessDeniedPath = new PathString("/Home/AccessDenied"); }) .AddCloudFoundryOAuth(Configuration) .Toggleable(); services.AddAuthorization(options => { options.AddPolicy("authenticated", policy => policy.RequireClaim("scope", "openid")); options.AddPolicy("elevated", policy => policy.RequireClaim("scope", "kill")); }); // use CF SSO if security is enabled // if (funnyquotesConfig.EnableSecurity) // { // authBuilder.AddCloudFoundryOAuth(Configuration); // } // else // { // // if security is disabled, add dummy auth processors. // // This is necessary because controller's [Authorize] attributes will throw if no auth provider is registered // authBuilder.AddToggleableSecurity(); // } }
public void Configuration(IAppBuilder app) { try { var httpConfig = new HttpConfiguration(); var env = Environment.GetEnvironmentVariable("ASPNET_ENVIRONMENT") ?? "development"; // standard variable in asp.net core for environment declaration var config = new ConfigurationBuilder() // asp.net core config provider .AddJsonFile("appsettings.json", false, false) .AddJsonFile($"appsettings.{env}.json", true) .AddEnvironmentVariables() .AddCloudFoundry() // maps VCAP environmental variables as a config provider .AddConfigServer() // adds spring config server as a config provider .Build(); var funnyQuotesConfig = new FunnyQuotesConfiguration(); config.GetSection("FunnyQuotes").Bind(funnyQuotesConfig); // -- container registration var builder = new ContainerBuilder(); // build up autofac container builder.RegisterOptions(); // allow injection of strongly typed config builder.RegisterDiscoveryClient(config); // register eureka service discovery // builder.RegisterLogging(config); // read log level settings from config // builder.Register(ctx => new DynamicLoggerProvider(new ConsoleLoggerSettings().FromConfiguration(config))) // add SteelToe dynamic logger. works similar to // .AsSelf() // console logger, but allows log levels to be altered // .As<ILoggerProvider>() // .SingleInstance(); builder.RegisterConfiguration(config); builder.RegisterCloudFoundryOptions(config); builder.RegisterMySqlConnection(config); builder.Register(ctx => // register EF context { var connString = ctx.Resolve <IDbConnection>().ConnectionString; return(new FunnyQuotesCookieDbContext(connString)); }); builder.RegisterApiControllers(Assembly.GetExecutingAssembly()); // register all controllers to be injectable builder.RegisterWebApiFilterProvider(httpConfig); // register autofac support for webapi filters builder.RegisterType <LoggerExceptionFilterAttribute>() // register global exception handler .AsWebApiExceptionFilterFor <ApiController>() .SingleInstance(); builder.RegisterCloudFoundryActuators(config); var container = builder.Build(); // compile the container // -- configure owin server httpConfig.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html")); // default to json instead of xml httpConfig.Routes.MapHttpRoute( // setup default routing for WebApi2 "DefaultApi", "api/{controller}/{action}" ); httpConfig.Routes.MapHttpRoute("Health", "{controller}/{action}", new { controller = "health", action = "health" }); // map "/" to basic health endpoint so the default PCF health check for HTTP 200 response is satisfied httpConfig.DependencyResolver = new AutofacWebApiDependencyResolver(container); // assign autofac to provide dependency injection on controllers // -- setup app pipeline app.UseAutofacMiddleware(container); // allows injection of dependencies into owin middleware if (funnyQuotesConfig.EnableSecurity) { app.UseCloudFoundryJwtBearerAuthentication(config); // add security integration for PCF SSO } else { app.Use <NoAuthenticationMiddleware>(); // dummy security provider which is necessary if you have secured actions on controllers } app.UseAutofacWebApi(httpConfig); // merges owin pipeline with autofac request lifecycle app.UseWebApi(httpConfig); // standard OWIN WebAPI2 app.UseCors(CorsOptions.AllowAll); container.StartDiscoveryClient(); // ensure that discovery client is started container.StartActuators(); var logger = container.Resolve <ILogger <Startup> >(); logger.LogInformation(">> App Started <<"); } catch (Exception e) { // given that logging is DI controlled it may not be initialized, just write directly to console Console.Error.WriteLine(e); throw; } }