// This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices([NotNull] IServiceCollection services) { string[] allowedClients = _configuration.GetSection("allowedClients") .Get <string[]>(); services // config .AddSingleton(_configuration) .AddSingleton(_environment) // logging .AddLogging(config => { config .AddDebug() .AddConsole() .AddSerilog(); }) .AddSingleton(typeof(ILogger <>), typeof(Logger <>)); if (_environment.IsDevelopment()) { services // Swagger .AddSwaggerGen(options => { options.Setup(_configuration, _environment) .AddJwtBearerSecurity(); //options.OperationFilter<FormFileFilter>(); options.ExampleFilters(); }) .AddSwaggerExamplesFromAssemblyOf <Startup>(); } services // Cookies .Configure <CookiePolicyOptions>(options => { // This lambda determines whether user consent for non-essential cookies is needed for a given request. options.CheckConsentNeeded = _ => true; options.MinimumSameSitePolicy = SameSiteMode.None; }) // FormOptions .Configure <FormOptions>(options => { options.ValueLengthLimit = int.MaxValue; options.MultipartBodyLengthLimit = int.MaxValue; options.MemoryBufferThreshold = int.MaxValue; }) // Helpers .AddHttpContextAccessor() // Image Builders .AddSingleton <IUserImageBuilder, UserImageBuilder>() // Mapper .AddAutoMapper((_, builder) => builder.AddProfile(new AutoMapperProfiles()), new[] { typeof(AutoMapperProfiles).Assembly }, ServiceLifetime.Singleton) // Database .AddDbContext <DataContext>(builder => { // https://docs.microsoft.com/en-us/ef/core/querying/tracking // https://stackoverflow.com/questions/12726878/global-setting-for-asnotracking //builder.UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking); IConfigurationSection dataSection = _configuration.GetSection("data"); bool enableLogging = dataSection.GetValue <bool>("logging"); if (enableLogging) { builder.UseLoggerFactory(LogFactoryHelper.ConsoleLoggerFactory) .EnableSensitiveDataLogging(); } builder.UseLazyLoadingProxies(); builder.UseSqlite(dataSection.GetConnectionString("DefaultConnection"), e => e.MigrationsAssembly(typeof(DataContext).Assembly.GetName().Name)); builder.EnableDetailedErrors(_environment.IsDevelopment()); } /*, ServiceLifetime.Singleton*/) // Add CityRepository for a special case: needs to be a Singleton .AddSingleton <ICityRepositoryBase>(provider => { // don't dispose the scope because it'll dispose the DataContext IServiceScope scope = provider.CreateScope(); IServiceProvider scopedProvider = scope.ServiceProvider; return(new CityRepository(scopedProvider.GetRequiredService <DataContext>(), _configuration, scopedProvider.GetService <ILogger <CityRepository> >())); }) // using Scrutor .Scan(scan => { // Add all repositories scan.FromAssemblyOf <DataContext>() // Repositories will have scoped life time .AddClasses(classes => classes.AssignableTo <IRepositoryBase>()) .UsingRegistrationStrategy(RegistrationStrategy.Skip) .AsImplementedInterfaces() .AsSelf() .WithScopedLifetime(); // Can also use this approach: (This will require DataContext to be registered as Singleton which is not recommended) //scan.FromAssemblyOf<DataContext>() // // Edit repositories will have scoped life time // .AddClasses(classes => classes.AssignableTo(typeof(IRepository<>))) // .UsingRegistrationStrategy(RegistrationStrategy.Skip) // .AsImplementedInterfaces() // .AsSelf() // .WithScopedLifetime() // // ReadOnly repositories will have singleton life time // .AddClasses(classes => classes.AssignableTo<IRepositoryBase>()) // .UsingRegistrationStrategy(RegistrationStrategy.Skip) // .AsImplementedInterfaces() // .AsSelf() // .WithSingletonLifetime(); // Add image builders scan.FromAssemblyOf <Startup>() .AddClasses(classes => classes.AssignableTo <IImageBuilder>()) .UsingRegistrationStrategy(RegistrationStrategy.Skip) .AsImplementedInterfaces() .AsSelf() .WithSingletonLifetime(); }) // Identity .AddIdentityCore <User>(options => { options.Stores.MaxLengthForKeys = 128; options.User.RequireUniqueEmail = true; }) .AddRoles <Role>() .AddEntityFrameworkStores <DataContext>() .AddUserManager <UserManager <User> >() .AddRoleManager <RoleManager <Role> >() .AddRoleValidator <RoleValidator <Role> >() .AddSignInManager <SignInManager <User> >() .AddDefaultTokenProviders(); services // IdentityServer //.AddIdentityServer() // .AddDeveloperSigningCredential() // .AddInMemoryPersistedGrants() // .AddInMemoryIdentityResources(Config.GetIdentityResources()) // .AddInMemoryApiResources(Config.GetApiResources()) // .AddInMemoryClients(Config.GetClients()) // .AddAspNetIdentity<User>() // Jwt Bearer .AddJwtBearerAuthentication() .AddCookie(options => { options.SlidingExpiration = true; options.LoginPath = "/users/login"; options.LogoutPath = "/users/logout"; options.ExpireTimeSpan = TimeSpan.FromMinutes(_configuration.GetValue("jwt:timeout", 20).NotBelow(5)); }) .AddJwtBearerOptions(options => { SecurityKey signingKey = SecurityKeyHelper.CreateSymmetricKey(_configuration.GetValue <string>("jwt:signingKey"), 256); //SecurityKey decryptionKey = SecurityKeyHelper.CreateSymmetricKey(_configuration.GetValue<string>("jwt:encryptionKey"), 256); options.Setup(signingKey, /*decryptionKey, */ _configuration, _environment.IsDevelopment()); }) .Services .AddAuthorization(options => { options.DefaultPolicy = new AuthorizationPolicyBuilder(JwtBearerDefaults.AuthenticationScheme) .RequireAuthenticatedUser() .RequireClaim(ClaimTypes.Role, Role.Roles) .Build(); options.AddPolicy(Role.Members, policy => { policy.AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme) .RequireAuthenticatedUser() .RequireClaim(ClaimTypes.Role, Role.Members) .RequireRole(Role.Members); }); options.AddPolicy(Role.Administrators, policy => { policy.AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme) .RequireAuthenticatedUser() .RequireClaim(ClaimTypes.Role, Role.Administrators) .RequireRole(Role.Administrators); }); }) // MVC .AddDefaultCorsPolicy(builder => builder.WithExposedHeaders("Set-Cookie"), allowedClients) .AddForwardedHeaders() // Filters .AddScoped <LogUserActivity>() .AddControllers() .AddNewtonsoftJson(options => { JsonHelper.SetDefaults(options.SerializerSettings, contractResolver: new CamelCasePropertyNamesContractResolver()); options.SerializerSettings.DateFormatHandling = DateFormatHandling.IsoDateFormat; JsonSerializerSettingsConverters allConverters = EnumHelper <JsonSerializerSettingsConverters> .GetAllFlags() & ~(JsonSerializerSettingsConverters.IsoDateTime | JsonSerializerSettingsConverters.JavaScriptDateTime | JsonSerializerSettingsConverters.UnixDateTime); options.SerializerSettings.AddConverters(allConverters); }); }
public static JsonSerializerSettings AddConverters([NotNull] this JsonSerializerSettings thisValue, JsonSerializerSettingsConverters convertersToAdd = JsonSerializerSettingsConverters.Default) { IList <JsonConverter> converters = thisValue.Converters; if (converters.IsReadOnly) { throw new ReadOnlyException(); } if (convertersToAdd == JsonSerializerSettingsConverters.Default) { convertersToAdd = EnumHelper <JsonSerializerSettingsConverters> .GetAllFlags(); } if (EnumHelper <JsonSerializerSettingsConverters> .HasFlag(convertersToAdd, JsonSerializerSettingsConverters.StringEnum | JsonSerializerSettingsConverters.StringEnumTranslation)) { convertersToAdd &= ~JsonSerializerSettingsConverters.StringEnumTranslation; } if (convertersToAdd.FastHasFlag(JsonSerializerSettingsConverters.Binary)) { converters.Add(new BinaryConverter()); } if (convertersToAdd.FastHasFlag(JsonSerializerSettingsConverters.DataSet)) { converters.Add(new DataSetConverter()); } if (convertersToAdd.FastHasFlag(JsonSerializerSettingsConverters.DataTable)) { converters.Add(new DataTableConverter()); } if (convertersToAdd.FastHasFlag(JsonSerializerSettingsConverters.EntityKeyMember)) { converters.Add(new EntityKeyMemberConverter()); } if (convertersToAdd.FastHasFlag(JsonSerializerSettingsConverters.ExpandoObject)) { converters.Add(new ExpandoObjectConverter()); } if (convertersToAdd.FastHasFlag(JsonSerializerSettingsConverters.IsoDateTime)) { converters.Add(new IsoDateTimeConverter()); } if (convertersToAdd.FastHasFlag(JsonSerializerSettingsConverters.JavaScriptDateTime)) { converters.Add(new JavaScriptDateTimeConverter()); } if (convertersToAdd.FastHasFlag(JsonSerializerSettingsConverters.UnixDateTime)) { converters.Add(new UnixDateTimeConverter()); } if (convertersToAdd.FastHasFlag(JsonSerializerSettingsConverters.KeyValuePair)) { converters.Add(new KeyValuePairConverter()); } if (convertersToAdd.FastHasFlag(JsonSerializerSettingsConverters.Regex)) { converters.Add(new RegexConverter()); } if (convertersToAdd.FastHasFlag(JsonSerializerSettingsConverters.StringEnumTranslation)) { converters.Add(new StringEnumTranslationConverter { Culture = thisValue.Culture }); } else if (convertersToAdd.FastHasFlag(JsonSerializerSettingsConverters.StringEnum)) { converters.Add(new StringEnumConverter()); } if (convertersToAdd.FastHasFlag(JsonSerializerSettingsConverters.Version)) { converters.Add(new VersionConverter()); } if (convertersToAdd.FastHasFlag(JsonSerializerSettingsConverters.XmlNode)) { converters.Add(new XmlNodeConverter()); } if (convertersToAdd.FastHasFlag(JsonSerializerSettingsConverters.Uri)) { converters.Add(new UriConverter()); } if (convertersToAdd.FastHasFlag(JsonSerializerSettingsConverters.Keys)) { converters.Add(new KeysConverter()); } return(thisValue); }