Пример #1
0
        public static IConveyBuilder AddInfrastructure(this IConveyBuilder builder)
        {
            builder.Services.AddSingleton <IJwtProvider, JwtProvider>();
            builder.Services.AddSingleton <IPasswordService, PasswordService>();
            builder.Services.AddSingleton <IPasswordHasher <IPasswordService>, PasswordHasher <IPasswordService> >();
            builder.Services.AddTransient <IIdentityService, IdentityService>();
            builder.Services.AddTransient <IRefreshTokenService, RefreshTokenService>();
            builder.Services.AddSingleton <IRng, Rng>();
            builder.Services.AddTransient <IMessageBroker, MessageBroker>();
            builder.Services.AddTransient <IRefreshTokenRepository, RefreshTokenRepository>();
            builder.Services.AddTransient <IUserRepository, UserRepository>();
            builder.Services.AddTransient <IAppContextFactory, AppContextFactory>();
            builder.Services.AddTransient(ctx => ctx.GetRequiredService <IAppContextFactory>().Create());
            builder.Services.TryDecorate(typeof(ICommandHandler <>), typeof(OutboxCommandHandlerDecorator <>));
            builder.Services.TryDecorate(typeof(IEventHandler <>), typeof(OutboxEventHandlerDecorator <>));

            return(builder
                   .AddErrorHandler <ExceptionToResponseMapper>()
                   .AddQueryHandlers()
                   .AddInMemoryQueryDispatcher()
                   .AddJwt()
                   .AddHttpClient()
                   .AddConsul()
                   .AddFabio()
                   .AddExceptionToMessageMapper <ExceptionToMessageMapper>()
                   .AddRabbitMq(plugins: p => p.AddJaegerRabbitMqPlugin())
                   .AddMessageOutbox(o => o.AddMongo())
                   .AddMongo()
                   .AddRedis()
                   .AddMetrics()
                   .AddJaeger()
                   .AddMongoRepository <RefreshTokenDocument, Guid>("refreshTokens")
                   .AddMongoRepository <UserDocument, Guid>("users")
                   .AddWebApiSwaggerDocs());
        }
        public static IConveyBuilder AddInfrastructure(this IConveyBuilder builder)
        {
            builder.Services
            .AddSingleton <IRequestStorage, RequestStorage>()
            .AddSingleton <IStoryRequestStorage, StoryRequestStorage>()
            .AddSingleton <IIdGenerator, IdGenerator>()
            .AddSingleton <RequestTypeMetricsMiddleware>()
            .AddSingleton <IClock, UtcClock>()
            .AddScoped <IMessageBroker, MessageBroker>()
            .AddScoped <IStoryRepository, StoryMongoRepository>()
            .AddScoped <IStoryRatingRepository, StoryRatingMongoRepository>()
            .AddScoped <IUserRepository, UserMongoRepository>()
            .AddScoped <IUsersApiClient, UsersApiHttpClient>()
            .AddTransient <IAppContextFactory, AppContextFactory>()
            .AddTransient(ctx => ctx.GetRequiredService <IAppContextFactory>().Create())
            .AddDomainEvents()
            .AddGrpc();

            if (builder.GetOptions <PrometheusOptions>("prometheus").Enabled)
            {
                builder.Services.TryDecorate(typeof(ICommandHandler <>), typeof(MetricsCommandHandlerDecorator <>));
            }

            if (builder.GetOptions <JaegerOptions>("jaeger").Enabled)
            {
                builder.Services.TryDecorate(typeof(ICommandHandler <>), typeof(TracingCommandHandlerDecorator <>));
            }

            builder.Services.TryDecorate(typeof(ICommandHandler <>), typeof(LoggingCommandHandlerDecorator <>));
            builder.Services.TryDecorate(typeof(IEventHandler <>), typeof(LoggingEventHandlerDecorator <>));


            builder.Services.TryDecorate(typeof(ICommandHandler <>), typeof(OutboxCommandHandlerDecorator <>));
            builder.Services.TryDecorate(typeof(IEventHandler <>), typeof(OutboxEventHandlerDecorator <>));

            builder
            .AddErrorHandler <ExceptionToResponseMapper>()
            .AddExceptionToMessageMapper <ExceptionToMessageMapper>()
            .AddQueryHandlers()
            .AddInMemoryQueryDispatcher()
            .AddHttpClient()
            .AddConsul()
            .AddFabio()
            .AddRabbitMq(plugins: p => p.AddJaegerRabbitMqPlugin())
            .AddMessageOutbox(o => o.AddMongo())
            .AddMongo()
            .AddRedis()
            .AddPrometheus()
            .AddJaeger()
            .AddMongoRepository <StoryDocument, long>("stories")
            .AddMongoRepository <UserDocument, Guid>("users")
            .AddWebApiSwaggerDocs()
            .AddCertificateAuthentication()
            .AddSecurity();

            builder.Services.AddScoped <LogContextMiddleware>()
            .AddSingleton <ICorrelationIdFactory, CorrelationIdFactory>();

            return(builder);
        }
        public static IConveyBuilder AddInfrastructure(this IConveyBuilder builder)
        {
            builder.Services.AddTransient <IMessageBroker, MessageBroker>();
            builder.Services.AddTransient <ISprintRepository, SprintRepository>();
            builder.Services.AddTransient <IProjectRepository, ProjectRepository>();
            builder.Services.AddTransient <IIssueRepository, IssueRepository>();
            builder.Services.AddTransient <IAppContextFactory, AppContextFactory>();
            builder.Services.AddTransient <IIdentityApiHttpClient, IdentityApiHttpClient>();
            builder.Services.AddTransient(ctx => ctx.GetRequiredService <IAppContextFactory>().Create());
            builder.Services.TryDecorate(typeof(ICommandHandler <>), typeof(OutboxCommandHandlerDecorator <>));
            builder.Services.TryDecorate(typeof(IEventHandler <>), typeof(OutboxEventHandlerDecorator <>));

            return(builder
                   .AddErrorHandler <ExceptionToResponseMapper>()
                   .AddQueryHandlers()
                   .AddInMemoryQueryDispatcher()
                   .AddJwt()
                   .AddHttpClient()
                   .AddConsul()
                   .AddFabio()
                   .AddExceptionToMessageMapper <ExceptionToMessageMapper>()
                   .AddRabbitMq(plugins: p => p.AddJaegerRabbitMqPlugin())
                   .AddMessageOutbox(o => o.AddMongo())
                   .AddMongo()
                   .AddRedis()
                   .AddJaeger()
                   .AddMongoRepository <IssueDocument, string>("issues")
                   .AddMongoRepository <ProjectDocument, string>("projects")
                   .AddMongoRepository <SprintDocument, string>("sprints")
                   .AddWebApiSwaggerDocs()
                   .AddSecurity());
        }
Пример #4
0
        public static IConveyBuilder AddInfrastructure(this IConveyBuilder builder)
        {
            builder.Services.AddTransient <IMessageBroker, MessageBroker>();
            builder.Services.AddTransient <ICourseRepository, CourseRepository>();
            builder.Services.AddTransient <ICourseModuleRepository, CourseModuleRepository>();
            builder.Services.AddTransient <ICourseEpisodeRepository, CourseEpisodeRepository>();
            builder.Services.AddSingleton <IDateTimeProvider, DateTimeProvider>();
            builder.Services.AddTransient <IAppContextFactory, AppContextFactory>();
            builder.Services.AddTransient(ctx => ctx.GetRequiredService <IAppContextFactory>().Create());
            builder.Services.TryDecorate(typeof(ICommandHandler <>), typeof(OutboxCommandHandlerDecorator <>));
            builder.Services.TryDecorate(typeof(IEventHandler <>), typeof(OutboxEventHandlerDecorator <>));

            return(builder
                   .AddErrorHandler <ExceptionToResponseMapper>()
                   .AddQueryHandlers()
                   .AddInMemoryQueryDispatcher()
                   .AddHttpClient()
                   .AddConsul()
                   .AddFabio()
                   .AddRabbitMq(plugins: p => p.AddJaegerRabbitMqPlugin())
                   .AddMessageOutbox(o => o.AddMongo())
                   .AddExceptionToMessageMapper <ExceptionToMessageMapper>()
                   .AddMongo()
                   .AddRedis()
                   .AddMetrics()
                   .AddJaeger()
                   .AddMongoRepository <CourseDocument, Guid>("courses")
                   .AddMongoRepository <CourseModuleDocument, Guid>("courseModules")
                   .AddMongoRepository <CourseEpisodeDocument, Guid>("courseEpisodes")
                   .AddWebApiSwaggerDocs());
        }
Пример #5
0
        public static IConveyBuilder AddInfrastructure(this IConveyBuilder builder)
        {
            var requestsOptions = builder.GetOptions <RequestsOptions>("requests");

            builder.Services.AddSingleton(requestsOptions);
            builder.Services.AddTransient <ICommandHandler <ICommand>, GenericCommandHandler <ICommand> >()
            .AddTransient <IEventHandler <IEvent>, GenericEventHandler <IEvent> >()
            .AddTransient <IEventHandler <IRejectedEvent>, GenericRejectedEventHandler <IRejectedEvent> >()
            .AddTransient <IHubService, HubService>()
            .AddTransient <IHubWrapper, HubWrapper>()
            .AddSingleton <IOperationsService, OperationsService>();
            builder.Services.AddGrpc();

            return(builder
                   .AddErrorHandler <ExceptionToResponseMapper>()
                   .AddJwt()
                   .AddCommandHandlers()
                   .AddEventHandlers()
                   .AddQueryHandlers()
                   .AddHttpClient()
                   .AddConsul()
                   .AddFabio()
                   .AddRabbitMq(plugins: p => p.AddJaegerRabbitMqPlugin())
                   .AddMongo()
                   .AddRedis()
                   .AddMetrics()
                   .AddJaeger()
                   .AddRedis()
                   .AddSignalR()
                   .AddWebApiSwaggerDocs()
                   .AddSecurity());
        }
        public static IConveyBuilder AddInfrastructure(this IConveyBuilder builder)
        {
            // Recordings
            builder.Services.AddTransient <IRecordingRepository, RedisRecordingRepository>();
            builder.Services.AddSingleton <IAuthorizationHandler, HasScopeHandler>();
            builder.Services.AddAuthorization(options =>
            {
                options.AddPolicy(PlaybackScopes.READ_PAYLOAD,
                                  policyBuilder => policyBuilder.Requirements.Add(
                                      new HasScopeRequirement(PlaybackScopes.READ_PAYLOAD,
                                                              "https://prometric.oktapreview.com/oauth2/ausu831293IEbvvD21d5")));
                options.AddPolicy(PlaybackScopes.WRITE_PAYLOAD,
                                  policyBuilder => policyBuilder.Requirements.Add(
                                      new HasScopeRequirement(PlaybackScopes.WRITE_PAYLOAD,
                                                              "https://prometric.oktapreview.com/oauth2/ausu831293IEbvvD21d5")));
            });

            return(builder
                   .AddErrorHandler <ExceptionToResponseMapper>()
                   .AddJwt()
                   .AddQueryHandlers()
                   .AddInMemoryQueryDispatcher()
                   .AddHandlersLogging()
                   .AddHttpClient()
                   .AddMetrics()
                   .AddRedis()
                   .AddWebApiSwaggerDocs());
        }
Пример #7
0
        public static IConveyBuilder AddInfrastructure(this IConveyBuilder builder)
        {
            builder.Services
            .AddScoped <LogContextMiddleware>()
            .AddSingleton <IRequestStorage, RequestStorage>()
            .AddSingleton <IStoryRequestStorage, StoryRequestStorage>()
            .AddSingleton <IStoryIdGenerator, StoryIdGenerator>()
            .AddSingleton <IDateTimeProvider, DateTimeProvider>()
            .AddScoped <IMessageBroker, MessageBroker>()
            .AddScoped <IStoryRepository, StoryMongoRepository>()
            .AddScoped <IStoryRatingRepository, StoryRatingMongoRepository>()
            .AddScoped <IUserRepository, UserMongoRepository>()
            .AddTransient <IAppContextFactory, AppContextFactory>()
            .AddTransient(ctx => ctx.GetRequiredService <IAppContextFactory>().Create())
            .AddGrpc();

            builder
            .AddErrorHandler <ExceptionToResponseMapper>()
            .AddExceptionToMessageMapper <ExceptionToMessageMapper>()
            .AddQueryHandlers()
            .AddInMemoryQueryDispatcher()
            .AddHttpClient()
            .AddMongo()
            .AddRedis()
            .AddRabbitMq()
            .AddMongoRepository <StoryDocument, long>("stories")
            .AddMongoRepository <UserDocument, Guid>("users")
            .AddWebApiSwaggerDocs();

            builder.Services.AddSingleton <ICorrelationIdFactory, CorrelationIdFactory>();

            return(builder);
        }
Пример #8
0
        public static IConveyBuilder AddInfrastructure(this IConveyBuilder builder)
        {
            builder.Services.AddTransient <IResourcesRepository, ResourcesMongoRepository>();

            builder
            .AddErrorHandler <ExceptionToResponseMapper>()
            .AddQueryHandlers()
            .AddInMemoryQueryDispatcher()
            .AddMongo()
            .AddMongoRepository <ResourceDocument, Guid>("resources")
            .AddRabbitMq();

            return(builder);
        }
Пример #9
0
        public static IConveyBuilder AddCore(this IConveyBuilder builder)
        {
            builder.Services.AddSingleton <IJwtProvider, JwtProvider>()
            .AddSingleton <IPasswordService, PasswordService>()
            .AddSingleton <IPasswordHasher <IPasswordService>, PasswordHasher <IPasswordService> >()
            .AddSingleton <IRng, Rng>()
            .AddSingleton <ITokenStorage, TokenStorage>()
            .AddScoped <IMessageBroker, MessageBroker>()
            .AddScoped <IFollowerRepository, FollowerRepository>()
            .AddScoped <IRefreshTokenRepository, RefreshTokenRepository>()
            .AddScoped <IUserRepository, UserRepository>();

            builder
            .AddErrorHandler <ExceptionToResponseMapper>()
            .AddExceptionToMessageMapper <ExceptionToMessageMapper>()
            .AddCommandHandlers()
            .AddEventHandlers()
            .AddQueryHandlers()
            .AddInMemoryCommandDispatcher()
            .AddInMemoryEventDispatcher()
            .AddInMemoryQueryDispatcher()
            .AddQueryHandlers()
            .AddInMemoryQueryDispatcher()
            .AddJwt()
            .AddHttpClient()
            .AddConsul()
            .AddFabio()
            .AddRabbitMq(plugins: p => p.AddJaegerRabbitMqPlugin())
            .AddMessageOutbox(o => o.AddMongo())
            .AddMongo()
            .AddRedis()
            .AddPrometheus()
            .AddJaeger()
            .AddMongoRepository <FollowerDocument, Guid>("followers")
            .AddMongoRepository <RefreshTokenDocument, Guid>("refreshTokens")
            .AddMongoRepository <UserDocument, Guid>("users")
            .AddWebApiSwaggerDocs()
            .AddSecurity();

            builder.Services.AddScoped <LogContextMiddleware>()
            .AddSingleton <ICorrelationIdFactory, CorrelationIdFactory>();

            builder.Services.TryDecorate(typeof(ICommandHandler <>), typeof(LoggingCommandHandlerDecorator <>));
            builder.Services.TryDecorate(typeof(IEventHandler <>), typeof(LoggingEventHandlerDecorator <>));
            builder.Services.TryDecorate(typeof(ICommandHandler <>), typeof(OutboxCommandHandlerDecorator <>));
            builder.Services.TryDecorate(typeof(IEventHandler <>), typeof(OutboxEventHandlerDecorator <>));

            return(builder);
        }
Пример #10
0
        public static IConveyBuilder AddInfrastructure(this IConveyBuilder builder)
        {
            builder.Services.AddTransient <ICustomersServiceClient, CustomersServiceClient>();
            builder.Services.AddTransient <ICustomerDiscountsService, CustomerDiscountsService>();

            return(builder
                   .AddErrorHandler <ExceptionToResponseMapper>()
                   .AddQueryHandlers()
                   .AddInMemoryQueryDispatcher()
                   .AddHttpClient()
                   .AddConsul()
                   .AddFabio()
                   .AddMetrics()
                   .AddJaeger()
                   .AddWebApiSwaggerDocs()
                   .AddSecurity());
        }
Пример #11
0
        public static IConveyBuilder AddCore(this IConveyBuilder builder)
        {
            builder.Services
            .AddSingleton <IHttpContextAccessor, HttpContextAccessor>()
            .AddScoped <IAdRepository, AdRepository>()
            .AddScoped <IMessageBroker, MessageBroker>()
            .AddScoped <IStoryApiClient, StoryApiHttpClient>()
            .AddScoped <IUsersApiClient, UsersApiHttpClient>();

            // builder.AddGrpc();

            builder
            .AddErrorHandler <ExceptionToResponseMapper>()
            .AddExceptionToMessageMapper <ExceptionToMessageMapper>()
            .AddCommandHandlers()
            .AddEventHandlers()
            .AddInMemoryCommandDispatcher()
            .AddInMemoryEventDispatcher()
            .AddQueryHandlers()
            .AddInMemoryQueryDispatcher()
            .AddJwt()
            .AddHttpClient()
            .AddConsul()
            .AddFabio()
            .AddRabbitMq(plugins: p => p.AddJaegerRabbitMqPlugin())
            .AddMessageOutbox(o => o.AddMongo())
            .AddMongo()
            .AddRedis()
            .AddPrometheus()
            .AddJaeger()
            .AddWebApiSwaggerDocs()
            .AddSecurity();

            builder.Services.AddScoped <LogContextMiddleware>()
            .AddSingleton <ICorrelationIdFactory, CorrelationIdFactory>();

            builder.Services.TryDecorate(typeof(ICommandHandler <>), typeof(LoggingCommandHandlerDecorator <>));
            builder.Services.TryDecorate(typeof(IEventHandler <>), typeof(LoggingEventHandlerDecorator <>));
            builder.Services.TryDecorate(typeof(ICommandHandler <>), typeof(OutboxCommandHandlerDecorator <>));
            builder.Services.TryDecorate(typeof(IEventHandler <>), typeof(OutboxEventHandlerDecorator <>));

            return(builder);
        }
        public static IConveyBuilder AddInfrastructure(this IConveyBuilder builder)
        {
            builder.Services.AddSingleton <IEventMapper, EventMapper>();
            builder.Services.AddTransient <IMessageBroker, MessageBroker>();
            builder.Services.AddTransient <IResourcesRepository, ResourcesMongoRepository>();
            builder.Services.AddTransient <ICustomersServiceClient, CustomersServiceClient>();
            builder.Services.AddSingleton <IDateTimeProvider, DateTimeProvider>();
            builder.Services.AddTransient <IAppContextFactory, AppContextFactory>();
            builder.Services.AddTransient <IEventProcessor, EventProcessor>();
            builder.Services.AddTransient(ctx => ctx.GetRequiredService <IAppContextFactory>().Create());
            builder.Services.AddHostedService <MetricsJob>();
            builder.Services.AddSingleton <CustomMetricsMiddleware>();
            builder.Services.TryDecorate(typeof(ICommandHandler <>), typeof(OutboxCommandHandlerDecorator <>));
            builder.Services.TryDecorate(typeof(IEventHandler <>), typeof(OutboxEventHandlerDecorator <>));
            builder.Services.Scan(s => s.FromAssemblies(AppDomain.CurrentDomain.GetAssemblies())
                                  .AddClasses(c => c.AssignableTo(typeof(IDomainEventHandler <>)))
                                  .AsImplementedInterfaces()
                                  .WithTransientLifetime());

            return(builder
                   .AddErrorHandler <ExceptionToResponseMapper>()
                   .AddQueryHandlers()
                   .AddInMemoryQueryDispatcher()
                   .AddHttpClient()
                   .AddConsul()
                   .AddFabio()
                   .AddRabbitMq(plugins: p => p.AddJaegerRabbitMqPlugin())
                   .AddMessageOutbox(o => o.AddMongo())
                   .AddExceptionToMessageMapper <ExceptionToMessageMapper>()
                   .AddMongo()
                   .AddRedis()
                   .AddMetrics()
                   .AddJaeger()
                   .AddJaegerDecorators()
                   .AddHandlersLogging()
                   .AddMongoRepository <ResourceDocument, Guid>("resources")
                   .AddWebApiSwaggerDocs()
                   .AddCertificateAuthentication()
                   .AddSecurity());
        }
Пример #13
0
        public static IConveyBuilder AddInfrastructure(this IConveyBuilder builder)
        {
            builder.Services.AddSingleton <IEventMapper, EventMapper>();
            builder.Services.AddTransient <IMessageBroker, MessageBroker>();
            builder.Services.AddSingleton <IDateTimeProvider, DateTimeProvider>();
            builder.Services.AddTransient <IEventProcessor, EventProcessor>();
            builder.Services.Scan(s => s.FromAssemblies(AppDomain.CurrentDomain.GetAssemblies())
                                  .AddClasses(c => c.AssignableTo(typeof(IDomainEventHandler <>)))
                                  .AsImplementedInterfaces()
                                  .WithTransientLifetime());

            return(builder
                   .AddErrorHandler <ExceptionToResponseMapper>()
                   .AddQueryHandlers()
                   .AddInMemoryQueryDispatcher()
                   .AddHttpClient()
                   .AddConsul()
                   .AddFabio()
                   .AddRabbitMq()
                   .AddExceptionToMessageMapper <ExceptionToMessageMapper>()
                   .AddMongo());
        }
Пример #14
0
        public static IConveyBuilder AddInfrastructure(this IConveyBuilder builder)
        {
            builder
            .AddErrorHandler <ExceptionToResponseMapper>()
            .AddHttpClient()
            .AddConsul()
            .AddFabio()
            .AddCommandHandlers()
            .AddEventHandlers()
            .AddInMemoryCommandDispatcher()
            .AddInMemoryEventDispatcher()
            .AddRedis()
            .AddMetrics()
            .AddRabbitMq()
            .AddWebApiSwaggerDocs()
            .AddSecurity();

            builder.Services.AddChronicle();
            builder.Services.AddTransient <IAvailabilityServiceClient, AvailabilityServiceClient>();
            builder.Services.AddTransient <IVehiclesServiceClient, VehiclesServiceClient>();
            builder.Services.AddTransient <IResourceReservationsService, ResourceReservationsService>();

            return(builder);
        }
Пример #15
0
        public static IConveyBuilder AddInfrastructure(this IConveyBuilder builder)
        {
            builder.Services.AddTransient <IAppContextFactory, AppContextFactory>();
            builder.Services.AddTransient(ctx => ctx.GetRequiredService <IAppContextFactory>().Create());
            builder.Services.TryDecorate(typeof(IEventHandler <>), typeof(OutboxEventHandlerDecorator <>));
            builder.Services.AddControllersWithViews();
            builder.Services.AddRazorPages().AddRazorRuntimeCompilation();

            return(builder
                   .AddErrorHandler <ExceptionToResponseMapper>()
                   .AddJwt()
                   .AddHttpClient()
                   .AddConsul()
                   .AddFabio()
                   .AddExceptionToMessageMapper <ExceptionToMessageMapper>()
                   .AddRabbitMq(plugins: p => p.AddJaegerRabbitMqPlugin())
                   .AddMessageOutbox(o => o.AddMongo())
                   .AddMongo()
                   .AddRedis()
                   .AddJaeger()
                   .AddWebApiSwaggerDocs()
                   .AddSecurity()
                   .AddEmailSender());
        }
Пример #16
0
        public static IConveyBuilder AddWebApi(this IConveyBuilder builder, Action <IMvcCoreBuilder> configureMvc = null,
                                               IJsonSerializer jsonSerializer = null, string sectionName = SectionName)
        {
            if (string.IsNullOrWhiteSpace(sectionName))
            {
                sectionName = SectionName;
            }

            if (!builder.TryRegister(RegistryName))
            {
                return(builder);
            }

            if (jsonSerializer is null)
            {
                var factory = new Open.Serialization.Json.Newtonsoft.JsonSerializerFactory(new JsonSerializerSettings
                {
                    ContractResolver = new CamelCasePropertyNamesContractResolver(),
                    Converters       = { new StringEnumConverter(true) }
                });
                jsonSerializer = factory.GetSerializer();
            }

            if (jsonSerializer.GetType().Namespace?.Contains("Newtonsoft") == true)
            {
                builder.Services.Configure <KestrelServerOptions>(o => o.AllowSynchronousIO = true);
                builder.Services.Configure <IISServerOptions>(o => o.AllowSynchronousIO     = true);
            }

            builder.Services.AddSingleton(jsonSerializer);
            builder.Services.AddSingleton <IHttpContextAccessor, HttpContextAccessor>();
            builder.Services.AddSingleton(new WebApiEndpointDefinitions());
            var options = builder.GetOptions <WebApiOptions>(sectionName);

            builder.Services.AddSingleton(options);
            _bindRequestFromRoute = options.BindRequestFromRoute;

            var mvcCoreBuilder = builder.Services
                                 .AddLogging()
                                 .AddMvcCore();

            mvcCoreBuilder.AddMvcOptions(o =>
            {
                o.OutputFormatters.Clear();
                o.OutputFormatters.Add(new JsonOutputFormatter(jsonSerializer));
                o.InputFormatters.Clear();
                o.InputFormatters.Add(new JsonInputFormatter(jsonSerializer));
            })
            .AddDataAnnotations()
            .AddApiExplorer()
            .AddAuthorization();

            configureMvc?.Invoke(mvcCoreBuilder);

            builder.Services.Scan(s =>
                                  s.FromAssemblies(AppDomain.CurrentDomain.GetAssemblies())
                                  .AddClasses(c => c.AssignableTo(typeof(IRequestHandler <,>)))
                                  .AsImplementedInterfaces()
                                  .WithTransientLifetime());

            builder.Services.AddTransient <IRequestDispatcher, RequestDispatcher>();
            builder.AddErrorHandler <EmptyExceptionToResponseMapper>();

            return(builder);
        }