// This method gets called by the runtime. Use this method to add services to the container.
        // For more information on how to configure your application, visit http://go.microsoft.com/fwlink/?LinkID=398940
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddOptions();

            services.AddCors(options =>
            {
                options.AddPolicy("AllowAllOrigins",
                                  builder =>
                {
                    builder
                    .AllowAnyOrigin()
                    .AllowAnyHeader()
                    .AllowAnyMethod()
                    .AllowCredentials();
                });
            });

            // Adds framework services.
            services.AddDbContext <FoodDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

            services.AddIdentity <IdentityUser, IdentityRole>()
            .AddEntityFrameworkStores <FoodDbContext>()
            .AddDefaultTokenProviders();

            services.AddRouting(options => options.LowercaseUrls = true);
            services.AddSingleton <IActionContextAccessor, ActionContextAccessor>();
            services.AddScoped <IUrlHelper>(implementationFactory =>
            {
                var actionContext = implementationFactory.GetService <IActionContextAccessor>().ActionContext;
                return(new UrlHelper(actionContext));
            });

            // Identity options.
            services.Configure <IdentityOptions>(options =>
            {
                // Password settings.
                options.Password.RequireDigit           = false;
                options.Password.RequiredLength         = 5;
                options.Password.RequireNonAlphanumeric = false;
                options.Password.RequireUppercase       = false;
                options.Password.RequireLowercase       = false;
            });

            services.AddSignalR();

            // Claims-Based Authorization: role claims.
            services.AddAuthorization(options =>
            {
                options.AddPolicy("Manage Accounts", policy => policy.RequireRole("administrator"));
                options.AddPolicy("Access Resources", policy => policy.RequireRole("administrator", "user"));
                options.AddPolicy("Modify Resources", policy => policy.RequireRole("administrator"));
            });

            services.AddIdentityServer()
            .AddDeveloperSigningCredential()
            .AddInMemoryPersistedGrants()
            .AddInMemoryIdentityResources(IdentityConfig.GetIdentityResources())
            .AddInMemoryApiResources(IdentityConfig.GetApiResources())
            .AddInMemoryClients(IdentityConfig.GetClients())
            .AddAspNetIdentity <IdentityUser>();

            services.AddAuthentication(IdentityServerAuthenticationDefaults.AuthenticationScheme)
            .AddIdentityServerAuthentication(options =>
            {
                options.Authority            = Configuration["IdentityServerEndpoint"];
                options.RequireHttpsMetadata = Configuration["IdentityServerEndpoint"].StartsWith("https");
                options.ApiName = "WebAPI";
            });

            services.AddScoped <IFoodRepository, EfFoodRepository>();
            services.AddSingleton <IIngredientRepository, IngredientRepository>();
            services.AddScoped <IEnsureDatabaseDataService, EnsureDatabaseDataService>();

            services.AddMvc().AddJsonOptions(options =>
            {
                options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
            });

            services.AddSwaggerGen(c =>
            {
                c.SwaggerDoc("v1", new Info {
                    Title = "FoodAPICore", Version = "v1"
                });
            });
        }
        // This method gets called by the runtime. Use this method to add services to the container.
        // For more information on how to configure your application, visit http://go.microsoft.com/fwlink/?LinkID=398940
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddOptions();

            services.AddCors(options =>
            {
                options.AddPolicy("AllowAllOrigins",
                                  builder =>
                {
                    builder
                    .AllowAnyOrigin()
                    .AllowAnyHeader()
                    .AllowAnyMethod();
                });
            });

            // Adds framework services.
            services.AddDbContext <FoodDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

            services.AddIdentity <IdentityUser, IdentityRole>()
            .AddEntityFrameworkStores <FoodDbContext>()
            .AddDefaultTokenProviders();

            // Identity options.
            services.Configure <IdentityOptions>(options =>
            {
                // Password settings.
                options.Password.RequireDigit           = false;
                options.Password.RequiredLength         = 5;
                options.Password.RequireNonAlphanumeric = false;
                options.Password.RequireUppercase       = false;
                options.Password.RequireLowercase       = false;
            });

            // Claims-Based Authorization: role claims.
            services.AddAuthorization(options =>
            {
                // Policy for dashboard: only administrator role.
                options.AddPolicy("Manage Accounts", policy => policy.RequireClaim("role", "administrator"));

                // Policy for resources: user or administrator role.
                options.AddPolicy("Modify Resources", policy => policy.RequireClaim("role", "administrator"));

                options.AddPolicy("Access Resources", policyBuilder => policyBuilder.RequireAssertion(
                                      context => context.User.HasClaim(claim => (claim.Type == "role" && claim.Value == "user") ||
                                                                       (claim.Type == "role" && claim.Value == "administrator"))
                                      )
                                  );
            });

            services.AddIdentityServer()
            .AddTemporarySigningCredential()
            .AddInMemoryIdentityResources(IdentityConfig.GetIdentityResources())
            .AddInMemoryApiResources(IdentityConfig.GetApiResources())
            .AddInMemoryClients(IdentityConfig.GetClients())
            .AddAspNetIdentity <IdentityUser>();   // IdentityServer4.AspNetIdentity.

            //var connectionString = Configuration["connectionStrings:DefaultConnection"];
            //services.AddDbContext<FoodDbContext>(options => options.UseSqlServer(connectionString));

            services.AddSingleton <IFoodRepository, FoodRepository>();
            services.AddScoped <IFoodRepository, EfFoodRepository>();
            services.AddSingleton <IIngredientRepository, IngredientRepository>();
            services.AddSingleton <IEnsureDatabaseDataService, EnsureDatabaseDataService>();

            services.AddMvc();

            services.AddSwaggerGen(c =>
            {
                c.SwaggerDoc("v1", new Info {
                    Title = "FoodAPICore", Version = "v1"
                });
            });
        }