예제 #1
0
        public void ConfigureContainer(ServiceRegistry services)
        {
            services.AddMvc();
            services.AddLogging();
            services.AddIdentityServer()
            .AddDeveloperSigningCredential()
            .AddInMemoryApiResources(Config.GetApiResources())
            .AddInMemoryClients(Config.GetClients());
            services.For <IMessageMaker>().Use(new MessageMaker("Hey there."));

            services.AddAuthentication()
            .AddIdentityServerAuthentication(options =>
            {
                options.Authority            = "auth";
                options.RequireHttpsMetadata = true;
            })


            .AddFacebook(facebookOptions =>
            {
                facebookOptions.AppId     = "something";
                facebookOptions.AppSecret = "else";
            });
        }
예제 #2
0
        // 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 https://go.microsoft.com/fwlink/?LinkID=398940
        public void ConfigureContainer(ServiceRegistry services)
        {
            services.AddMiniProfiler(opt =>
            {
                // opt.RouteBasePath = "/profiler";
                opt.ShouldProfile             = _ => true;
                opt.ShowControls              = true;
                opt.StackMaxLength            = short.MaxValue;
                opt.PopupStartHidden          = false;
                opt.PopupShowTrivial          = true;
                opt.PopupShowTimeWithChildren = true;
            });

            services.AddHttpsRedirection(options => options.HttpsPort = 443);

            // If environment is localhost, then enable CORS policy, otherwise no cross-origin access
            services.AddCors(options => options.AddPolicy("CorsPolicy", builder => builder
                                                          .WithOrigins(_configuration.GetSection("TrustedSpaUrls").Get <string[]>())
                                                          .AllowAnyHeader()
                                                          .AllowAnyMethod()
                                                          .AllowCredentials()));

            // Add framework services
            // Add functionality to inject IOptions<T>
            services.AddOptions();

            services.AddResponseCompression();

            services.Configure <JwtSettings>(_configuration.GetSection("JwtSettings"));

            services.AddLogging();

            services.AddRouting(options => options.LowercaseUrls = true);

            if (_env.IsDevelopment())
            {
                services.AddDistributedMemoryCache();
            }
            else
            {
                var redisConnectionString =
                    ConnectionStringUrlToRedisResource(_configuration.GetValue <string>("REDISTOGO_URL"));

                services.AddStackExchangeRedisCache(c => c.Configuration = redisConnectionString);
            }

            services.AddSession(options =>
            {
                // Set a short timeout for easy testing.
                options.IdleTimeout         = TimeSpan.FromMinutes(60);
                options.Cookie.HttpOnly     = true;
                options.Cookie.Name         = ApiConstants.AuthenticationSessionCookieName;
                options.Cookie.SecurePolicy = CookieSecurePolicy.None;
            });

            services.AddSwaggerGen(c =>
            {
                c.SwaggerDoc("v1", new OpenApiInfo {
                    Title = "Stream-Ripper-API", Version = "v1"
                });

                // Set the comments path for the Swagger JSON and UI.
                var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
                var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);

                if (File.Exists(xmlPath))
                {
                    c.IncludeXmlComments(xmlPath);
                }

                c.AddSecurityDefinition("Bearer",
                                        new OpenApiSecurityScheme
                {
                    Description = "JWT Authorization header using the Bearer scheme.",
                    Type        = SecuritySchemeType.Http,
                    Scheme      = "bearer"
                });
            });

            services.AddMvc(x =>
            {
                x.ModelValidatorProviders.Clear();

                // Not need to have https
                x.RequireHttpsPermanent = false;

                // Allow anonymous for localhost
                if (_env.IsDevelopment())
                {
                    x.Filters.Add <AllowAnonymousFilter>();
                }

                // Exception filter attribute
                x.Filters.Add <ExceptionFilterAttribute>();
            }).AddNewtonsoftJson(x =>
            {
                x.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
            })
            .AddRazorPagesOptions(x => x.Conventions.ConfigureFilter(new IgnoreAntiforgeryTokenAttribute()));

            services.AddDbContext <EntityDbContext>(opt =>
            {
                if (_env.IsDevelopment())
                {
                    opt.UseSqlite(_configuration.GetValue <string>("ConnectionStrings:Sqlite"));
                }
                else
                {
                    var postgresConnectionString =
                        ConnectionStringUrlToPgResource(_configuration.GetValue <string>("DATABASE_URL")
                                                        ?? throw new Exception("DATABASE_URL is null"));
                    opt.UseNpgsql(postgresConnectionString);
                }
            });

            services.AddIdentity <User, IdentityRole <int> >(x => x.User.RequireUniqueEmail = true)
            .AddEntityFrameworkStores <EntityDbContext>()
            .AddRoles <IdentityRole <int> >()
            .AddDefaultTokenProviders();

            // L2 EF cache
            if (_env.IsDevelopment())
            {
                services.AddEFSecondLevelCache(options =>
                                               options.UseEasyCachingCoreProvider("memory").DisableLogging(true)
                                               );

                services.AddEasyCaching(options => options.UseInMemory("memory"));
            }
            else
            {
                services.AddEFSecondLevelCache(options =>
                                               options.UseEasyCachingCoreProvider("redis").DisableLogging(true));

                services.AddEasyCaching(options =>
                {
                    var(_, dictionary) = UrlUtility.UrlToResource(_configuration.GetValue <string>("REDISTOGO_URL"));

                    // use memory cache with your own configuration
                    options.UseRedis(x =>
                    {
                        x.DBConfig.Endpoints.Add(
                            new EasyCaching.Core.Configurations.ServerEndPoint(dictionary["Host"],
                                                                               int.Parse(dictionary["Port"])));
                        x.DBConfig.Username           = dictionary["Username"];
                        x.DBConfig.Password           = dictionary["Password"];
                        x.DBConfig.AbortOnConnectFail = false;
                    });
                });
            }

            services.AddEfRepository <EntityDbContext>(x =>
            {
                x.Profiles(Assembly.Load("Dal"), Assembly.Load("Models"));
            });

            var jwtSetting = _configuration
                             .GetSection("JwtSettings")
                             .Get <JwtSettings>();

            if (_env.IsDevelopment() && string.IsNullOrEmpty(jwtSetting.Key))
            {
                jwtSetting.Key =
                    "DCk2T4guOWvu8WRklEEmKazH5gqUJQnyCYXfzFJQU84tY0iJFeUJc2yIQqkqJ4od8AQvyXdlOFP0Q0QGWzB84W4hWFptL8APynvt";

                IdentityModelEventSource.ShowPII = true;
            }

            services.AddAuthentication(options =>
            {
                options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                options.DefaultChallengeScheme    = JwtBearerDefaults.AuthenticationScheme;
            })
            .AddJwtBearer(config =>
            {
                config.RequireHttpsMetadata = false;
                config.SaveToken            = true;

                config.TokenValidationParameters = new TokenValidationParameters
                {
                    ValidIssuer      = jwtSetting.Issuer,
                    ValidAudience    = jwtSetting.Audience,
                    IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtSetting.Key))
                };
            });

            services.For <JwtSettings>().Use(jwtSetting).Singleton();

            // If environment is localhost then use mock email service
            if (_env.IsDevelopment())
            {
                services.For <IS3Service>().Use(new S3Service()).Singleton();
            }
            else
            {
                var(accessKeyId, secretAccessKey, url) = (
                    _configuration.GetRequiredValue <string>("CLOUDCUBE_ACCESS_KEY_ID"),
                    _configuration.GetRequiredValue <string>("CLOUDCUBE_SECRET_ACCESS_KEY"),
                    _configuration.GetRequiredValue <string>("CLOUDCUBE_URL")
                    );

                var          prefix     = new Uri(url).Segments.GetValue(1)?.ToString();
                const string bucketName = "cloud-cube";

                // Generally bad practice
                var credentials = new BasicAWSCredentials(accessKeyId, secretAccessKey);

                // Create S3 client
                services.For <IAmazonS3>().Use(new AmazonS3Client(credentials, RegionEndpoint.USEast1));
                services.For <S3ServiceConfig>().Use(new S3ServiceConfig(bucketName, prefix));

                services.For <IS3Service>().Use(ctx => new S3Service(
                                                    ctx.GetInstance <ILogger <S3Service> >(),
                                                    ctx.GetInstance <IAmazonS3>(),
                                                    ctx.GetInstance <S3ServiceConfig>()
                                                    ));
            }

            // Register stuff in container, using the StructureMap APIs...
            services.Scan(_ =>
            {
                _.AssemblyContainingType(typeof(Startup));
                _.Assembly("Api");
                _.Assembly("Logic");
                _.Assembly("Dal");
                _.WithDefaultConventions();
            });
        }
예제 #3
0
        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureContainer(ServiceRegistry services)
        {
            services.Configure <CookiePolicyOptions>(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.AddDbContext <FutureAgroIdentityDbContext>(options =>
                                                                options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")), ServiceLifetime.Transient);

            services.AddIdentityCore <IdentityUser>(options =>
            {
                options.Password.RequireNonAlphanumeric = false;
                options.Password.RequireUppercase       = false;
                options.Password.RequireLowercase       = false;
                options.Password.RequireDigit           = false;
            })
            .AddDefaultTokenProviders()
            .AddSignInManager()
            .AddEntityFrameworkStores <FutureAgroIdentityDbContext>();

            services.AddAuthentication(options =>
            {
                options.DefaultAuthenticateScheme = IdentityConstants.ApplicationScheme;
                options.DefaultChallengeScheme    = IdentityConstants.ApplicationScheme;
                options.DefaultSignInScheme       = IdentityConstants.ExternalScheme;
            })
            .AddCookie(cookieOptions =>
            {
                cookieOptions.AccessDeniedPath = "/Account/Login";
                cookieOptions.LoginPath        = "/Account/Login";
                cookieOptions.LogoutPath       = "/Account/Login";
            })
            .AddGoogle(options =>
            {
                // Provide the Google Client ID
                options.ClientId = "84213285064-3bu6c7f6iuov5e2nj71j8kp09ldsgg8p.apps.googleusercontent.com";
                // Register with User Secrets using:
                // dotnet user-secrets set "Authentication:Google:ClientId" "{Client ID}"

                // Provide the Google Client Secret
                options.ClientSecret = "USukES39oKelSIhWjI5Nj2W6";
                // Register with User Secrets using:
                // dotnet user-secrets set "Authentication:Google:ClientSecret" "{Client Secret}"

                options.ClaimActions.MapJsonKey("urn:google:picture", "picture", "url");
                options.ClaimActions.MapJsonKey("urn:google:locale", "locale", "string");
                options.SaveTokens = true;

                options.Events.OnCreatingTicket = ctx =>
                {
                    List <AuthenticationToken> tokens = ctx.Properties.GetTokens().ToList();

                    tokens.Add(new AuthenticationToken()
                    {
                        Name  = "TicketCreated",
                        Value = DateTime.UtcNow.ToString()
                    });

                    ctx.Properties.StoreTokens(tokens);

                    return(Task.CompletedTask);
                };
            })
            .AddIdentityCookies();

            services.AddMvc()
            .SetCompatibilityVersion(CompatibilityVersion.Version_2_1);

            services.ConfigureApplicationCookie(options =>
            {
                // Cookie settings
                options.Cookie.HttpOnly   = true;
                options.ExpireTimeSpan    = TimeSpan.FromMinutes(5);
                options.LoginPath         = "/Account/Login";
                options.AccessDeniedPath  = "/Account/Login";
                options.LogoutPath        = "/Account/Login";
                options.SlidingExpiration = true;
            });

            services.AddSignalR(options =>
            {
                //options.EnableDetailedErrors = true;
            });

            // Also exposes Lamar specific registrations
            // and functionality
            services.Scan(s =>
            {
                s.AssembliesAndExecutablesFromApplicationBaseDirectory();
                s.WithDefaultConventions();
            });

            services.AddSingleton <ILector, LectorTemperatura>();
            services.AddTransient <TemperaturaRepository>();

            services.AddSingleton <ILector, LectorHumedad>();
            services.AddTransient <HumedadRepository>();

            services.AddSingleton <ILector, LectorLuminosidad>();
            services.AddTransient <LuminosidadRepository>();

            services.AddSingleton <ILector, LectorCrecimiento>();
            services.AddSingleton <ILector, LectorPlantasMuertas>();
            services.AddTransient <PlantasRepository>();

            services.AddSingleton <ServicioCrecimiento>();
            services.AddSingleton <ServicioTemperatura>();
            services.AddSingleton <ServicioHumedad>();
            services.AddSingleton <ServicioLuminosidad>();
        }
예제 #4
0
        public void ConfigureContainer(ServiceRegistry services)
        {
            services.AddLogging(config =>
            {
                config.ClearProviders();

                config.AddConfiguration(Configuration.GetSection("Logging"));
                config.AddApplicationInsights();
            });

            //Response Compression - https://docs.microsoft.com/en-us/aspnet/core/performance/response-compression?view=aspnetcore-5.0
            services.AddResponseCompression();

            services.AddCors(options =>
            {
                options.AddPolicy("SpecificOrigins",
                                  builder =>
                {
                    builder.WithOrigins("https://tmireact.azurewebsites.net", "https://theminiindex.com", "https://wwww.theminiindex.com", "http://localhost:3000")
                    .AllowAnyHeader()
                    .AllowAnyMethod();
                });
            });

            services.Configure <CookiePolicyOptions>(options =>
            {
                options.CheckConsentNeeded    = context => true;
                options.MinimumSameSitePolicy = SameSiteMode.None;
            });

            services.AddSwaggerGen();

            services.AddDefaultIdentity <IdentityUser>()
            .AddRoles <IdentityRole>()
            .AddEntityFrameworkStores <MiniIndexContext>();

            services.AddHangfire(configuration => configuration
                                 .SetDataCompatibilityLevel(CompatibilityLevel.Version_170)
                                 .UseSimpleAssemblyNameTypeSerializer()
                                 .UseRecommendedSerializerSettings()
                                 .UseSqlServerStorage(Configuration.GetConnectionString("HangfireConnection"), new SqlServerStorageOptions
            {
                CommandBatchMaxTimeout       = TimeSpan.FromMinutes(5),
                SlidingInvisibilityTimeout   = TimeSpan.FromMinutes(5),
                QueuePollInterval            = TimeSpan.Zero,
                UseRecommendedIsolationLevel = true,
                DisableGlobalLocks           = true
            }));
            services.AddHangfireServer();

            services
            .AddMvc()
            .SetCompatibilityVersion(CompatibilityVersion.Version_3_0)
            .AddRazorOptions(ConfigureRazor);

            services.AddDbContext <MiniIndexContext>(ConfigureEntityFramework);

            string facebookAppId     = Configuration["Authentication:Facebook:AppId"];
            string facebookAppSecret = Configuration["Authentication:Facebook:AppSecret"];

            if (facebookAppId != null && facebookAppSecret != null)
            {
                services.AddAuthentication()
                .AddFacebook(facebookOptions =>
                {
                    facebookOptions.AppId     = facebookAppId;
                    facebookOptions.AppSecret = facebookAppSecret;
                });
            }

            services.AddTransient <IEmailSender, EmailSender>();
            services.Configure <AuthMessageSenderOptions>(Configuration);
            services.AddApplicationInsightsTelemetry();
            services.AddSingleton <IHttpContextAccessor, HttpContextAccessor>();
            services.AddSingleton <ITelemetryInitializer, TelemetryEnrichment>();
            services.AddApplicationInsightsTelemetryProcessor <AppInsightsFilter>();
            services.Configure <AzureStorageConfig>(Configuration.GetSection("AzureStorageConfig"));

            services.IncludeRegistry <CoreServices>();
            services.IncludeRegistry <WebAppServices>();
        }
예제 #5
0
        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureContainer(ServiceRegistry services)
        {
            services.AddMvc().AddControllersAsServices()
            .AddJsonOptions(x =>
            {
                x.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter());
                x.JsonSerializerOptions.MaxDepth = 255;
            });
            services.AddSpaStaticFiles(configuration =>
            {
                configuration.RootPath = "ClientApp";
            });

            services.AddEntityFrameworkSqlServer();

            #region setupAuthAndSwagger

            services.AddAuthentication(c =>
            {
                c.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                c.DefaultChallengeScheme    = JwtBearerDefaults.AuthenticationScheme;
            })
            .AddJwtBearer(options =>
            {
                options.TokenValidationParameters = new TokenValidationParameters
                {
                    // Clock skew compensates for server time drift.
                    // We recommend 5 minutes or less:
                    ClockSkew = TimeSpan.FromMinutes(5),
                    // Specify the key used to sign the token:
                    IssuerSigningKey    = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("VerticalToDoKeyVerticalToDoKeyVerticalToDoKey")),
                    RequireSignedTokens = true,
                    // Ensure the token hasn't expired:
                    RequireExpirationTime = true,
                    ValidateLifetime      = true,
                    // Ensure the token audience matches our audience value (default true):
                    ValidateAudience = false,
                    // Ensure the token was issued by a trusted authorization server (default true):
                    ValidateIssuer = false,
                };
            });
            services.AddSwaggerGen(c =>
            {
                c.SwaggerDoc("v1", new OpenApiInfo {
                    Title = "Vertical ToDo API", Version = "v1"
                });
                c.CustomSchemaIds((t) =>
                {
                    return(t.FullName.Replace("+", ""));
                });
                c.AddSecurityDefinition(JwtBearerDefaults.AuthenticationScheme, new OpenApiSecurityScheme
                {
                    Name         = "Authorization",
                    Type         = SecuritySchemeType.ApiKey,
                    Scheme       = JwtBearerDefaults.AuthenticationScheme,
                    BearerFormat = "JWT",
                    In           = ParameterLocation.Header,
                    Description  = "JWT Authorization header using the Bearer scheme."
                });
                c.AddSecurityRequirement(new OpenApiSecurityRequirement
                {
                    {
                        new OpenApiSecurityScheme
                        {
                            Reference = new OpenApiReference
                            {
                                Type = ReferenceType.SecurityScheme,
                                Id   = JwtBearerDefaults.AuthenticationScheme
                            }
                        },
                        new string[] {}
                    }
                });
            });

            #endregion

            services.For <IConfiguration>().Use(Configuration);
            services.For <IHttpContextAccessor>().Use <HttpContextAccessor>();
            services.AddDbContext <VerticalToDoDbContext>(o => o.UseSqlServer(Configuration.GetConnectionString("VerticalToDo")));
            services.SetupRegistries();

            var c = new Container(services);
            var a = c.Model.For <AccountsController>().Default.DescribeBuildPlan();
            var q = c.WhatDoIHave();
        }
예제 #6
0
 public void ConfigureContainer(ServiceRegistry services)
 {
     services.AddMvc();
     services.AddLogging();
 }
예제 #7
0
        // 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 https://go.microsoft.com/fwlink/?LinkID=398940
        public void ConfigureContainer(ServiceRegistry services)
        {
            services.AddMiniProfiler(opt =>
            {
                // opt.RouteBasePath = "/profiler";
                opt.ShouldProfile             = _ => true;
                opt.ShowControls              = true;
                opt.StackMaxLength            = short.MaxValue;
                opt.PopupStartHidden          = false;
                opt.PopupShowTrivial          = true;
                opt.PopupShowTimeWithChildren = true;
            });

            services.AddHttpsRedirection(options => options.HttpsPort = 443);

            // Add framework services
            // Add functionality to inject IOptions<T>
            services.AddOptions();

            services.AddResponseCompression();

            services.AddLogging();

            services.AddRouting(options => options.LowercaseUrls = true);

            services.AddDistributedMemoryCache();

            services.AddSession(options =>
            {
                // Set a short timeout for easy testing.
                options.IdleTimeout         = TimeSpan.FromMinutes(60);
                options.Cookie.HttpOnly     = true;
                options.Cookie.Name         = ApiConstants.AuthenticationSessionCookieName;
                options.Cookie.SecurePolicy = CookieSecurePolicy.None;
            });

            // Make sure a JS engine is registered, or you will get an error!
            services.AddJsEngineSwitcher(options => options.DefaultEngineName = ChakraCoreJsEngine.EngineName)
            .AddChakraCore();

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

                // Set the comments path for the Swagger JSON and UI.
                var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
                var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);

                if (File.Exists(xmlPath))
                {
                    c.IncludeXmlComments(xmlPath);
                }

                c.AddSecurityDefinition("Bearer", // Name the security scheme
                                        new OpenApiSecurityScheme
                {
                    Description = "JWT Authorization header using the Bearer scheme.",
                    Type        = SecuritySchemeType.Http,
                    Scheme      = "bearer"
                });
            });

            services.AddMvc(x =>
            {
                // Not need to have https
                x.RequireHttpsPermanent = false;

                // Allow anonymous for localhost
                if (_env.IsDevelopment())
                {
                    x.Filters.Add <AllowAnonymousFilter>();
                }

                // Exception filter attribute
                x.Filters.Add <ExceptionFilterAttribute>();
            })
            .AddViewOptions(x =>
            {
                x.HtmlHelperOptions.ClientValidationEnabled = true;
            })
            .AddNewtonsoftJson(x =>
            {
                x.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
                x.SerializerSettings.Converters.Add(new StringEnumConverter {
                    NamingStrategy = new CamelCaseNamingStrategy()
                });
                x.SerializerSettings.ContractResolver =
                    new CamelCasePropertyNamesContractResolver();

                x.SerializerSettings.ContractResolver = new IgnoreUserContractResolver();
            })
            .AddRazorPagesOptions(x => x.Conventions.ConfigureFilter(new IgnoreAntiforgeryTokenAttribute()));

            services.AddWebMarkupMin(opt =>
            {
                opt.AllowMinificationInDevelopmentEnvironment = true;
                opt.AllowCompressionInDevelopmentEnvironment  = true;
            })
            .AddHtmlMinification()
            .AddHttpCompression();

            // If using Kestrel:
            services.Configure <KestrelServerOptions>(options =>
            {
                options.AllowSynchronousIO = true;
            });

            // If using IIS:
            services.Configure <IISServerOptions>(options =>
            {
                options.AllowSynchronousIO = true;
            });

            services.AddDbContext <EntityDbContext>(opt =>
            {
                if (_env.IsDevelopment())
                {
                    opt.UseSqlite(_configuration.GetValue <string>("ConnectionStrings:Sqlite"));
                }
                else
                {
                    var postgresConnectionString =
                        ConnectionStringUrlToPgResource(_configuration.GetValue <string>("DATABASE_URL")
                                                        ?? throw new Exception("DATABASE_URL is null"));
                    opt.UseNpgsql(postgresConnectionString);
                }
            }, ServiceLifetime.Transient);

            services.AddIdentity <User, IdentityRole <int> >(x => x.User.RequireUniqueEmail = true)
            .AddEntityFrameworkStores <EntityDbContext>()
            .AddRoles <IdentityRole <int> >()
            .AddDefaultTokenProviders();

            // L2 EF cache
            if (_env.IsDevelopment())
            {
                services.AddEFSecondLevelCache(options =>
                                               options.UseEasyCachingCoreProvider("memory").DisableLogging(true)
                                               );

                services.AddEasyCaching(options => options.UseInMemory("memory"));
            }
            else
            {
                services.AddEFSecondLevelCache(options =>
                                               options.UseEasyCachingCoreProvider("redis").DisableLogging(true));

                services.AddEasyCaching(options =>
                {
                    var(_, dictionary) = UrlUtility.UrlToResource(_configuration.GetValue <string>("REDISTOGO_URL"));

                    // use memory cache with your own configuration
                    options.UseRedis(x =>
                    {
                        x.DBConfig.Endpoints.Add(new ServerEndPoint(dictionary["Host"], int.Parse(dictionary["Port"])));
                        x.DBConfig.Username           = dictionary["Username"];
                        x.DBConfig.Password           = dictionary["Password"];
                        x.DBConfig.AbortOnConnectFail = false;
                    });
                });
            }

            services.AddEfRepository <EntityDbContext>(x =>
            {
                x.Profiles(Assembly.Load("Dal"), Assembly.Load("Models"));
            });

            services.AddAutoMapper(Assembly.Load("Models"));

            services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme).AddCookie(x =>
            {
                x.Cookie.MaxAge = TimeSpan.FromMinutes(60);
                x.LoginPath     = new PathString("/Login/");
                x.LogoutPath    = new PathString("/Logout/");
            });

            services.For <GlobalConfigs>().Use(new GlobalConfigs()).Singleton();

            // Initialize the email jet client
            services.For <IMailjetClient>().Use(new MailjetClient(
                                                    _configuration.GetValue <string>("MAIL_JET_KEY"),
                                                    _configuration.GetValue <string>("MAIL_JET_SECRET"))
                                                ).Singleton();

            // If environment is localhost then use mock email service
            if (_env.IsDevelopment())
            {
                services.For <IS3Service>().Use(new S3Service()).Singleton();
                services.For <IEmailServiceApi>().Use(new EmailServiceApi()).Singleton();
            }
            else
            {
                var(accessKeyId, secretAccessKey, url) = (
                    _configuration.GetRequiredValue <string>("CLOUDCUBE_ACCESS_KEY_ID"),
                    _configuration.GetRequiredValue <string>("CLOUDCUBE_SECRET_ACCESS_KEY"),
                    _configuration.GetRequiredValue <string>("CLOUDCUBE_URL")
                    );

                var          prefix     = new Uri(url).Segments.GetValue(1)?.ToString();
                const string bucketName = "cloud-cube";

                // Generally bad practice
                var credentials = new BasicAWSCredentials(accessKeyId, secretAccessKey);

                // Create S3 client
                services.For <IAmazonS3>().Use(new AmazonS3Client(credentials, RegionEndpoint.USEast1));
                services.For <S3ServiceConfig>().Use(new S3ServiceConfig(bucketName, prefix));

                services.For <IS3Service>().Use(ctx => new S3Service(
                                                    ctx.GetInstance <ILogger <S3Service> >(),
                                                    ctx.GetInstance <IAmazonS3>(),
                                                    ctx.GetInstance <S3ServiceConfig>()
                                                    ));

                services.For <MailGunConfig>().Use(new MailGunConfig
                {
                    ApiKey = _configuration.GetRequiredValue <string>("MAILGUN_API_KEY"),
                    Domain = _configuration.GetRequiredValue <string>("MAILGUN_DOMAIN")
                });
            }

            // Register stuff in container, using the StructureMap APIs...
            services.Scan(_ =>
            {
                _.AssemblyContainingType(typeof(Startup));
                _.Assembly("Api");
                _.Assembly("Logic");
                _.Assembly("Dal");
                _.WithDefaultConventions();
            });
        }