/// <summary> /// サービス構成処理。 /// </summary> /// <param name="services"><see cref="IServiceCollection"/></param> public void ConfigureServices(IServiceCollection services) { services.AddAutoMapper(typeof(Startup)); services.Configure <AppSettings>(Configuration.GetSection("AppSettings")); services.Configure <EnvSettings>(Configuration.GetSection("EnvSettings")); services.Configure <DBSettings>(options => { Configuration.GetSection("DBSettings").Bind(options); options.SqlProviderFactory = SqlClientFactory.Instance; }); // This is work around. See https://github.com/dotnet/aspnetcore/issues/4853 @zhurinvlad commented on 5 Sep 2018 services.AddSingleton <IValidationAttributeAdapterProvider, CustomValidationAttributeAdapterProvider>(); services.AddSingleton <IConfigureOptions <MvcOptions>, MvcConfiguration>(); services.AddTransient <IAppSettings>(x => x.GetService <IOptionsMonitor <AppSettings> >().CurrentValue); services.AddTransient <IEnvSettings>(x => x.GetService <IOptionsMonitor <EnvSettings> >().CurrentValue); services.AddTransient <IDBSettings>(x => x.GetService <IOptionsMonitor <DBSettings> >().CurrentValue); services.AddTransient <IAccessTokenRepository, AccessTokenRepository>(); services.AddTransient <IAccountQueryService, AccountQueryService>(); services.AddTransient <IAccountRepository, AccountRepository>(); services.AddTransient <IAccountService, AccountService>(); services.AddTransient <IApplicationRepository, ApplicationRepository>(); services.AddTransient <IAuthorizationCodeRepository, AuthorizationCodeRepository>(); services.AddTransient <IAuthorizeService, AuthorizeService>(); services.AddTransient <IGroupPersonRepository, GroupPersonRepository>(); services.AddTransient <IGroupQueryService, GroupQueryService>(); services.AddTransient <IGroupRepository, GroupRepository>(); services.AddTransient <IGroupService, GroupService>(); services.AddTransient <IPersonQueryService, PersonQueryService>(); services.AddTransient <IPersonRepository, PersonRepository>(); services.AddTransient <IPersonService, PersonService>(); services.AddTransient <IProjectPersonRepository, ProjectPersonRepository>(); services.AddTransient <IProjectQueryService, ProjectQueryService>(); services.AddTransient <IProjectRepository, ProjectRepository>(); services.AddTransient <IProjectService, ProjectService>(); services.AddTransient <ITagRepository, TagRepository>(); services.AddTransient <IWorkTypeQueryService, WorkTypeQueryService>(); services.AddTransient <IWorkTypeRepository, WorkTypeRepository>(); services.AddTransient <IWorkTypeService, WorkTypeService>(); if (!WebHostEnvironment.IsProduction()) { services.AddCors(options => { options.AddDefaultPolicy(builder => { builder.WithOrigins("https://localhost:8443") .AllowCredentials() .AllowAnyMethod() .AllowAnyHeader(); builder.WithOrigins("https://editor.swagger.io") .AllowCredentials() .AllowAnyMethod() .AllowAnyHeader(); builder.WithOrigins("https://watertrans.stoplight.io") .AllowCredentials() .AllowAnyMethod() .AllowAnyHeader(); }); }); } services.AddAuthentication(BearerAuthenticationHandler.SchemeName) .AddScheme <AuthenticationSchemeOptions, BearerAuthenticationHandler>(BearerAuthenticationHandler.SchemeName, null); services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme) .AddMicrosoftIdentityWebApp(options => { Configuration.Bind("AzureAD", options); options.Events.OnSignedOutCallbackRedirect = context => { context.Response.Redirect("/"); context.HandleResponse(); return(Task.CompletedTask); }; options.Events.OnTokenValidated = context => { return(Task.CompletedTask); }; }); services.AddRazorPages().AddMicrosoftIdentityUI(); services.AddAuthorization(options => { options.AddPolicy(Policies.FullControlScopePolicy, policy => { policy.RequireClaim(Scopes.ClaimType, Scopes.FullControl); }); options.AddPolicy(Policies.ReadScopePolicy, policy => { policy.RequireClaim(Scopes.ClaimType, Scopes.FullControl, Scopes.Read, Scopes.Write, Scopes.User); }); options.AddPolicy(Policies.WriteScopePolicy, policy => { policy.RequireClaim(Scopes.ClaimType, Scopes.FullControl, Scopes.Write); }); }); services.AddApiVersioning(); services.AddVersionedApiExplorer(options => { options.GroupNameFormat = "'v'V"; options.SubstituteApiVersionInUrl = true; }); services.AddControllers(options => { options.Filters.Add(typeof(CatchAllExceptionFilter)); }) .AddJsonOptions(options => { options.JsonSerializerOptions.Encoder = JavaScriptEncoder.Create(UnicodeRanges.All); options.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter()); options.JsonSerializerOptions.IgnoreNullValues = true; }) .ConfigureApiBehaviorOptions(options => { options.InvalidModelStateResponseFactory = context => { return(ErrorObjectResultFactory.ValidationError(context.ModelState)); }; }) .AddDataAnnotationsLocalization(options => { options.DataAnnotationLocalizerProvider = (type, factory) => factory.Create(typeof(ErrorMessages)); }); services.AddSwaggerGen(options => { options.EnableAnnotations(); options.SwaggerGeneratorOptions.DescribeAllParametersInCamelCase = true; options.SwaggerDoc("v1", new OpenApiInfo { Title = "DailyReport Web Api", Version = "v1" }); options.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme { Description = "アクセストークンを入力してください。", Name = "Authorization", In = ParameterLocation.Header, Type = SecuritySchemeType.Http, Scheme = "bearer", }); options.AddSecurityRequirement(new OpenApiSecurityRequirement { { new OpenApiSecurityScheme { Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "Bearer", }, }, new string[] { } }, }); }); }