private void RegisterComponents(IServiceCollection builder)
        {
            builder.AddSingleton <IBatchProfilingOptions, BatchProfilingOptions>();
            builder.AddSingleton <IBatchProfilingService, BatchProfilingService>();
            builder.AddSingleton <IProducerConsumerFactory, ProducerConsumerFactory>();

            builder.AddSingleton <IReProfilingResponseMapper, ReProfilingResponseMapper>();

            builder.AddSingleton <IBatchUploadQueryService, BatchUploadQueryService>();
            builder.AddSingleton <IUniqueIdentifierProvider, UniqueIdentifierProvider>();
            builder.AddSingleton <IBatchUploadValidationService, BatchUploadValidationService>();
            builder.AddSingleton <IBatchUploadReaderFactory, BatchUploadReaderFactory>();
            builder.AddSingleton <IValidator <BatchUploadValidationRequest>, BatchUploadValidationRequestValidation>();

            builder.AddSingleton <IPublishedProviderUpdateDateService, PublishedProviderUpdateDateService>();

            ISqlSettings sqlSettings = new SqlSettings();

            Configuration.Bind("saSql", sqlSettings);

            builder.AddSingleton(sqlSettings);

            builder.AddSingleton <IBatchUploadService, BatchUploadService>();

            builder.AddScoped <IDataTableImporter, DataTableImporter>();
            builder.AddScoped <ISqlImportContextBuilder, SqlImportContextBuilder>();
            builder.AddSingleton <ISqlPolicyFactory, SqlPolicyFactory>();
            builder.AddScoped <ISqlConnectionFactory, SqlConnectionFactory>();
            builder.AddScoped <ISqlImportContextBuilder, SqlImportContextBuilder>();
            builder.AddScoped <ISqlImporter, SqlImporter>();
            builder.AddScoped <ISqlImportService, SqlImportService>();
            builder.AddScoped <ISqlNameGenerator, SqlNameGenerator>();
            builder.AddScoped <ISqlSchemaGenerator, SqlSchemaGenerator>();
            builder.AddScoped <IQaSchemaService, QaSchemaService>();
            builder.AddScoped <IQaRepository, QaRepository>();
            builder.AddSingleton <ITemplateMetadataResolver>(ctx =>
            {
                TemplateMetadataResolver resolver = new TemplateMetadataResolver();
                ILogger logger = ctx.GetService <ILogger>();

                TemplateMetadataSchema10.TemplateMetadataGenerator schema10Generator = new TemplateMetadataSchema10.TemplateMetadataGenerator(logger);
                resolver.Register("1.0", schema10Generator);

                TemplateMetadataSchema11.TemplateMetadataGenerator schema11Generator = new TemplateMetadataSchema11.TemplateMetadataGenerator(logger);
                resolver.Register("1.1", schema11Generator);

                return(resolver);
            });
            builder.AddSingleton <ICosmosRepository, CosmosRepository>();

            CosmosDbSettings settings = new CosmosDbSettings();

            Configuration.Bind("CosmosDbSettings", settings);

            settings.ContainerName = "publishedfunding";

            builder.AddSingleton(settings);

            builder.AddSingleton <IPublishedFundingContentsGeneratorResolver>(ctx =>
            {
                PublishedFundingContentsGeneratorResolver resolver = new PublishedFundingContentsGeneratorResolver();

                resolver.Register("1.0", new Generators.Schema10.PublishedFundingContentsGenerator());
                resolver.Register("1.1", new Generators.Schema11.PublishedFundingContentsGenerator());

                return(resolver);
            });

            builder.AddSingleton <IPublishedFundingIdGeneratorResolver>(ctx =>
            {
                PublishedFundingIdGeneratorResolver resolver = new PublishedFundingIdGeneratorResolver();

                IPublishedFundingIdGenerator v10Generator = new Generators.Schema10.PublishedFundingIdGenerator();

                resolver.Register("1.0", v10Generator);
                resolver.Register("1.1", v10Generator);

                return(resolver);
            });

            builder.AddSingleton <IProfilePatternPreview, ProfilePatternPreview>();
            builder.AddSingleton <IReProfilingRequestBuilder, ReProfilingRequestBuilder>();
            builder.AddSingleton <IUserProfileProvider, UserProfileProvider>();

            builder
            .AddSingleton <IHealthChecker, ControllerResolverHealthCheck>();

            builder.AddSingleton <IProfileHistoryService, ProfileHistoryService>();
            builder.AddSingleton <IDateTimeProvider, DateTimeProvider>();
            builder
            .AddSingleton <IPublishedProviderVersionService, PublishedProviderVersionService>()
            .AddSingleton <IHealthChecker, PublishedProviderVersionService>();
            builder.AddSingleton <ISpecificationFundingStatusService, SpecificationFundingStatusService>();
            builder
            .AddSingleton <IPublishedSearchService, PublishedSearchService>()
            .AddSingleton <IHealthChecker, PublishedSearchService>();

            builder.AddSingleton <IPoliciesService, PoliciesService>();
            builder.AddSingleton <IPublishedProviderStatusService, PublishedProviderStatusService>();
            builder.AddScoped <IProfileTotalsService, ProfileTotalsService>();
            builder.AddSingleton <IFundingConfigurationService, FundingConfigurationService>();

            builder.AddScoped <IFundingStreamPaymentDatesQuery, FundingStreamPaymentDatesQuery>();
            builder.AddScoped <IFundingStreamPaymentDatesIngestion, FundingStreamPaymentDatesIngestion>();
            builder.AddSingleton <ICsvUtils, CsvUtils>();
            builder.AddScoped <ICustomProfileService, CustomProfilingService>();
            builder.AddScoped <IValidator <ApplyCustomProfileRequest>, ApplyCustomProfileRequestValidator>();
            builder.AddSingleton <IPublishedProviderStatusUpdateService, PublishedProviderStatusUpdateService>();
            builder.AddSingleton <IPublishedProviderVersioningService, PublishedProviderVersioningService>();
            builder.AddSingleton <IJobTracker, JobTracker>();
            builder.AddSingleton <IJobManagement, JobManagement>();
            builder.AddSingleton <IVersionRepository <PublishedProviderVersion>, VersionRepository <PublishedProviderVersion> >((ctx) =>
            {
                CosmosDbSettings settings = new CosmosDbSettings();

                Configuration.Bind("CosmosDbSettings", settings);

                settings.ContainerName = "publishedfunding";

                CosmosRepository cosmos = new CosmosRepository(settings);

                return(new VersionRepository <PublishedProviderVersion>(cosmos, new NewVersionBuilderFactory <PublishedProviderVersion>()));
            });
            builder.AddSingleton <IVersionBulkRepository <PublishedProviderVersion>, VersionBulkRepository <PublishedProviderVersion> >((ctx) =>
            {
                CosmosDbSettings settings = new CosmosDbSettings();

                Configuration.Bind("CosmosDbSettings", settings);

                settings.ContainerName = "publishedfunding";

                CosmosRepository cosmos = new CosmosRepository(settings);

                return(new VersionBulkRepository <PublishedProviderVersion>(cosmos, new NewVersionBuilderFactory <PublishedProviderVersion>()));
            });
            builder
            .AddSingleton <IPublishedProviderStatusUpdateSettings>(_ =>
            {
                PublishedProviderStatusUpdateSettings settings = new PublishedProviderStatusUpdateSettings();

                Configuration.Bind("PublishedProviderStatusUpdateSettings", settings);

                return(settings);
            }
                                                                   );
            builder.AddHttpClient(HttpClientKeys.Profiling,
                                  c =>
            {
                ApiOptions apiOptions = new ApiOptions();

                Configuration.Bind("providerProfilingClient", apiOptions);

                Services.Core.Extensions.ServiceCollectionExtensions.SetDefaultApiClientConfigurationOptions(c, apiOptions, builder);
            })
            .ConfigurePrimaryHttpMessageHandler(() => new ApiClientHandler())
            .AddTransientHttpErrorPolicy(c => c.WaitAndRetryAsync(new[] { TimeSpan.FromMilliseconds(500), TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(5) }))
            .AddTransientHttpErrorPolicy(c => c.CircuitBreakerAsync(100, TimeSpan.FromSeconds(30)));

            builder.AddSingleton <IFundingStreamPaymentDatesRepository>((ctx) =>
            {
                CosmosDbSettings cosmosSettings = new CosmosDbSettings();

                Configuration.Bind("CosmosDbSettings", cosmosSettings);

                cosmosSettings.ContainerName = "profiling";

                return(new FundingStreamPaymentDatesRepository(new CosmosRepository(cosmosSettings)));
            });

            builder
            .AddSingleton <IPublishedFundingQueryBuilder, PublishedFundingQueryBuilder>();

            builder.AddSingleton <IPublishedFundingRepository, PublishedFundingRepository>((ctx) =>
            {
                CosmosDbSettings settings = new CosmosDbSettings();

                Configuration.Bind("CosmosDbSettings", settings);

                settings.ContainerName = "publishedfunding";

                CosmosRepository calcsCosmosRepository = new CosmosRepository(settings);
                IPublishedFundingQueryBuilder publishedFundingQueryBuilder = ctx.GetService <IPublishedFundingQueryBuilder>();

                return(new PublishedFundingRepository(calcsCosmosRepository, publishedFundingQueryBuilder));
            });

            builder
            .AddSingleton <IPublishingEngineOptions>(_ => new PublishingEngineOptions(Configuration));

            builder.AddSingleton <IPublishedFundingBulkRepository, PublishedFundingBulkRepository>((ctx) =>
            {
                CosmosDbSettings settings = new CosmosDbSettings();

                Configuration.Bind("CosmosDbSettings", settings);

                settings.ContainerName = "publishedfunding";

                IPublishingEngineOptions publishingEngineOptions = ctx.GetService <IPublishingEngineOptions>();

                CosmosRepository calcsCosmosRepository = new CosmosRepository(settings, publishingEngineOptions.AllowBatching ? new CosmosClientOptions
                {
                    ConnectionMode = ConnectionMode.Direct,
                    RequestTimeout = new TimeSpan(0, 0, 15),
                    MaxRequestsPerTcpConnection  = publishingEngineOptions.MaxRequestsPerTcpConnectionPublishedFundingCosmosBulkOptions,
                    MaxTcpConnectionsPerEndpoint = 4,
                    ConsistencyLevel             = ConsistencyLevel.Eventual,
                    AllowBulkExecution           = true
                } : null);

                IPublishingResiliencePolicies publishingResiliencePolicies = ctx.GetService <IPublishingResiliencePolicies>();

                return(new PublishedFundingBulkRepository(publishingResiliencePolicies, publishingEngineOptions, calcsCosmosRepository));
            });

            builder
            .AddSingleton <IBlobClient, BlobClient>((ctx) =>
            {
                BlobStorageOptions storageSettings = new BlobStorageOptions();

                Configuration.Bind("AzureStorageSettings", storageSettings);

                storageSettings.ContainerName = "publishedproviderversions";

                IBlobContainerRepository blobContainerRepository = new BlobContainerRepository(storageSettings);
                return(new BlobClient(blobContainerRepository));
            });

            builder.AddCaching(Configuration);
            builder.AddSearch(Configuration);
            builder
            .AddSingleton <ISearchRepository <PublishedProviderIndex>, SearchRepository <PublishedProviderIndex> >();
            builder
            .AddSingleton <ISearchRepository <PublishedFundingIndex>, SearchRepository <PublishedFundingIndex> >();

            builder
            .AddSingleton <IPublishedProviderProfilingService, PublishedProviderProfilingService>()
            .AddSingleton <IPublishedProviderErrorDetection, PublishedProviderErrorDetection>()
            .AddSingleton <IErrorDetectionStrategyLocator, ErrorDetectionStrategyLocator>()
            .AddSingleton <IDetectPublishedProviderErrors, FundingLineValueProfileMismatchErrorDetector>()
            .AddSingleton <IProfilingService, ProfilingService>()
            .AddSingleton <IHealthChecker, ProfilingService>()
            .AddSingleton <IPublishedProviderVersioningService, PublishedProviderVersioningService>();

            builder.AddApplicationInsightsTelemetry();
            builder.AddApplicationInsightsTelemetryClient(Configuration, "CalculateFunding.Api.Publishing");
            builder.AddApplicationInsightsServiceName(Configuration, "CalculateFunding.Api.Publishing");
            builder.AddLogging("CalculateFunding.Api.Publishing");
            builder.AddTelemetry();

            builder.AddServiceBus(Configuration, "publishing");

            builder.AddApiKeyMiddlewareSettings((IConfigurationRoot)Configuration);
            builder.AddPolicySettings(Configuration);
            builder.AddHttpContextAccessor();
            builder.AddHealthCheckMiddleware();

            builder.AddHttpCachingMvc();
            builder.AddQueryProviderAndExtractorForViewModelMvc <PublishedProviderFundingStructure, PublishedProviderFundingStructureTimedEtagProvider, PublishedProviderFundingStructureTimedEtagExtractor>(false);

            builder.AddPublishingServices(Configuration);
            builder.AddSpecificationsInterServiceClient(Configuration);
            builder.AddProvidersInterServiceClient(Configuration);
            builder.AddCalculationsInterServiceClient(Configuration);
            builder.AddProfilingInterServiceClient(Configuration);
            builder.AddJobsInterServiceClient(Configuration);
            builder.AddPoliciesInterServiceClient(Configuration);
            builder.AddFundingDataServiceInterServiceClient(Configuration);
            builder.AddFeatureToggling(Configuration);

            builder.AddScoped <IPublishedFundingUndoJobService, PublishedFundingUndoJobService>();
            builder.AddScoped <IPublishedFundingUndoJobCreation, PublishedFundingUndoJobCreation>();
            builder.AddScoped <IPublishedFundingUndoTaskFactoryLocator, PublishedFundingUndoTaskFactoryLocator>();
            builder.AddSingleton <IPublishedFundingUndoTaskFactory, SoftDeletePublishedFundingUndoTaskFactory>();
            builder.AddSingleton <IPublishedFundingUndoTaskFactory, HardDeletePublishedFundingUndoTaskFactory>();
            builder.AddSingleton <IPublishedFundingUndoCosmosRepository>(ctx =>
            {
                CosmosDbSettings settings = new CosmosDbSettings();

                Configuration.Bind("CosmosDbSettings", settings);

                settings.ContainerName = "publishedfunding";

                return(new PublishedFundingUndoCosmosRepository(ctx.GetService <IPublishingResiliencePolicies>(),
                                                                new CosmosRepository(settings)));
            });
            builder.AddSingleton <IPublishedFundingUndoBlobStoreRepository>(ctx =>
            {
                BlobStorageOptions settings = new BlobStorageOptions();

                Configuration.Bind("AzureStorageSettings", settings);

                settings.ContainerName = "publishedproviderversions";

                IBlobContainerRepository blobContainerRepository = new BlobContainerRepository(settings);
                return(new PublishedFundingUndoBlobStoreRepository(new BlobClient(blobContainerRepository),
                                                                   ctx.GetService <IPublishingResiliencePolicies>(),
                                                                   ctx.GetService <ILogger>()));
            });

            builder.AddSingleton <IProducerConsumerFactory, ProducerConsumerFactory>();

            builder
            .AddSingleton <LocalIBlobClient, LocalBlobClient>((ctx) =>
            {
                AzureStorageSettings storageSettings = new AzureStorageSettings();

                Configuration.Bind("AzureStorageSettings", storageSettings);

                storageSettings.ContainerName = "publishedfunding";

                return(new LocalBlobClient(storageSettings));
            });

            MapperConfiguration resultsConfig = new MapperConfiguration(c =>
            {
                c.AddProfile <PublishingServiceMappingProfile>();
            });

            builder.AddSingleton(resultsConfig.CreateMapper());

            builder.AddSingleton <IPublishingResiliencePolicies>(ctx =>
            {
                PolicySettings policySettings = ctx.GetService <PolicySettings>();

                AsyncBulkheadPolicy totalNetworkRequestsPolicy = ResiliencePolicyHelpers.GenerateTotalNetworkRequestsPolicy(policySettings);

                return(new ResiliencePolicies
                {
                    SpecificationsRepositoryPolicy = ResiliencePolicyHelpers.GenerateRestRepositoryPolicy(totalNetworkRequestsPolicy),
                    ProvidersApiClient = ResiliencePolicyHelpers.GenerateRestRepositoryPolicy(totalNetworkRequestsPolicy),
                    JobsApiClient = ResiliencePolicyHelpers.GenerateRestRepositoryPolicy(totalNetworkRequestsPolicy),
                    CalculationsApiClient = ResiliencePolicyHelpers.GenerateRestRepositoryPolicy(totalNetworkRequestsPolicy),
                    PublishedFundingRepository = CosmosResiliencePolicyHelper.GenerateCosmosPolicy(),
                    PublishedProviderVersionRepository = CosmosResiliencePolicyHelper.GenerateCosmosPolicy(totalNetworkRequestsPolicy),
                    BlobClient = ResiliencePolicyHelpers.GenerateRestRepositoryPolicy(totalNetworkRequestsPolicy),
                    PoliciesApiClient = ResiliencePolicyHelpers.GenerateRestRepositoryPolicy(totalNetworkRequestsPolicy),
                    ProfilingApiClient = ResiliencePolicyHelpers.GenerateRestRepositoryPolicy(totalNetworkRequestsPolicy),
                    PublishedIndexSearchResiliencePolicy = PublishedIndexSearchResiliencePolicy.GeneratePublishedIndexSearch(),
                    PublishedProviderSearchRepository = PublishedIndexSearchResiliencePolicy.GeneratePublishedIndexSearch(),
                    SpecificationsApiClient = ResiliencePolicyHelpers.GenerateRestRepositoryPolicy(totalNetworkRequestsPolicy),
                    FundingStreamPaymentDatesRepository = CosmosResiliencePolicyHelper.GenerateCosmosPolicy(totalNetworkRequestsPolicy)
                });
            });

            builder.AddSingleton <IJobManagementResiliencePolicies>((ctx) =>
            {
                PolicySettings policySettings = ctx.GetService <PolicySettings>();

                AsyncBulkheadPolicy totalNetworkRequestsPolicy = ResiliencePolicyHelpers.GenerateTotalNetworkRequestsPolicy(policySettings);

                return(new JobManagementResiliencePolicies()
                {
                    JobsApiClient = ResiliencePolicyHelpers.GenerateRestRepositoryPolicy(totalNetworkRequestsPolicy),
                });
            });

            builder.AddSingleton <IPublishedProviderFundingCountProcessor, PublishedProviderFundingCountProcessor>();
            builder.AddSingleton <IPublishedProviderFundingCsvDataProcessor, PublishedProviderFundingCsvDataProcessor>();

            if (Configuration.IsSwaggerEnabled())
            {
                builder.ConfigureSwaggerServices(title: "Publishing Microservice API");
            }
        }
        public void SetupStepContexts()
        {
            PublishingResiliencePolicies publishingResiliencePolicies = new PublishingResiliencePolicies()
            {
                BlobClient                           = Policy.NoOpAsync(),
                CalculationsApiClient                = Policy.NoOpAsync(),
                FundingFeedSearchRepository          = Policy.NoOpAsync(),
                JobsApiClient                        = Policy.NoOpAsync(),
                PoliciesApiClient                    = Policy.NoOpAsync(),
                ProfilingApiClient                   = Policy.NoOpAsync(),
                ProvidersApiClient                   = Policy.NoOpAsync(),
                PublishedFundingBlobRepository       = Policy.NoOpAsync(),
                PublishedFundingRepository           = Policy.NoOpAsync(),
                PublishedProviderVersionRepository   = Policy.NoOpAsync(),
                CalculationResultsRepository         = Policy.NoOpAsync(),
                SpecificationsRepositoryPolicy       = Policy.NoOpAsync(),
                SpecificationsApiClient              = Policy.NoOpAsync(),
                PublishedProviderSearchRepository    = Policy.NoOpAsync(),
                PublishedIndexSearchResiliencePolicy = Policy.NoOpAsync(),
                CacheProvider                        = Policy.NoOpAsync()
            };

            RegisterInstanceAs <ILogger>(new LoggerConfiguration().CreateLogger());
            RegisterInstanceAs <IPublishingResiliencePolicies>(publishingResiliencePolicies);
            RegisterInstanceAs <IConfiguration>(new ConfigurationBuilder().Build());

            RegisterTypeAs <InMemoryBlobClient, IBlobClient>();
            RegisterTypeAs <InMemoryAzureBlobClient, Services.Core.Interfaces.AzureStorage.IBlobClient>();
            RegisterTypeAs <InMemoryCosmosRepository, ICosmosRepository>();
            RegisterTypeAs <SpecificationInMemoryRepository, ISpecificationService>();
            RegisterTypeAs <JobsInMemoryRepository, IJobsApiClient>();
            RegisterTypeAs <InMemoryFeatureManagerSnapshot, IFeatureManagerSnapshot>();
            RegisterTypeAs <PublishedProviderInMemorySearchRepository, ISearchRepository <PublishedProviderIndex> >();
            RegisterTypeAs <ReApplyCustomProfiles, IReApplyCustomProfiles>();
            RegisterTypeAs <ReProfilingResponseMapper, IReProfilingResponseMapper>();
            RegisterTypeAs <ReProfilingRequestBuilder, IReProfilingRequestBuilder>();

            IMapper mapper = new MapperConfiguration(c =>
            {
                c.AddProfile <PublishingServiceMappingProfile>();
            }).CreateMapper();

            RegisterInstanceAs(mapper);

            JobManagementResiliencePolicies jobManagementResiliencePolicies = new JobManagementResiliencePolicies()
            {
                JobsApiClient = Policy.NoOpAsync(),
            };

            RegisterInstanceAs <IJobManagementResiliencePolicies>(jobManagementResiliencePolicies);
            RegisterTypeAs <JobTracker, IJobTracker>();
            RegisterTypeAs <JobManagement, IJobManagement>();
            RegisterTypeAs <InMemoryPublishedFundingRepository, IPublishedFundingRepository>();
            RegisterTypeAs <InMemoryPublishedFundingBulkRepository, IPublishedFundingBulkRepository>();
            RegisterTypeAs <PoliciesInMemoryRepository, IPoliciesApiClient>();
            RegisterTypeAs <InMemoryCacheProvider, ICacheProvider>();
            RegisterTypeAs <InMemoryMessengerService, IMessengerService>();

            ProvidersInMemoryClient providersInMemoryClient = new ProvidersInMemoryClient(mapper);

            RegisterInstanceAs <IProvidersApiClient>(providersInMemoryClient);
            RegisterTypeAs <ProviderService, IProviderService>();
            RegisterTypeAs <PublishedFundingService, IPublishedFundingService>();
            RegisterTypeAs <PoliciesService, IPoliciesService>();
            RegisterTypeAs <VariationService, IVariationService>();
            RegisterTypeAs <PublishedFundingDateService, IPublishedFundingDateService>();
            RegisterTypeAs <PublishServiceAcceptanceStepContext, IPublishFundingStepContext>();
            RegisterTypeAs <CurrentSpecificationStepContext, ICurrentSpecificationStepContext>();
            RegisterTypeAs <JobStepContext, IJobStepContext>();
            RegisterTypeAs <CurrentJobStepContext, ICurrentJobStepContext>();
            RegisterTypeAs <PublishedFundingRepositoryStepContext, IPublishedFundingRepositoryStepContext>();
            RegisterTypeAs <PoliciesStepContext, IPoliciesStepContext>();
            RegisterTypeAs <LoggerStepContext, ILoggerStepContext>();
            RegisterTypeAs <ProvidersStepContext, IProvidersStepContext>();
            RegisterTypeAs <PublishingDatesStepContext, IPublishingDatesStepContext>();
            RegisterTypeAs <PublishedFundingResultStepContext, IPublishedFundingResultStepContext>();
            RegisterTypeAs <PublishedProviderStepContext, IPublishedProviderStepContext>();
            RegisterTypeAs <ProfilingService, IProfilingService>();
            RegisterTypeAs <ProfilingInMemoryClient, IProfilingApiClient>();
            RegisterTypeAs <FDZInMemoryClient, IFundingDataZoneApiClient>();
            RegisterTypeAs <PublishedFundingDataService, IPublishedFundingDataService>();
            RegisterTypeAs <PublishedFundingVersionDataService, IPublishedFundingVersionDataService>();
            RegisterTypeAs <CalculationResultsService, ICalculationResultsService>();
            RegisterTypeAs <PublishingEngineOptions, IPublishingEngineOptions>();
            RegisterTypeAs <PublishedProviderVersionInMemoryRepository, IVersionRepository <PublishedProviderVersion> >();
            RegisterTypeAs <PublishedProviderVersionBulkInMemoryRepository, IVersionBulkRepository <PublishedProviderVersion> >();
            RegisterTypeAs <PublishedFundingVersionInMemoryRepository, IVersionRepository <PublishedFundingVersion> >();
            RegisterTypeAs <PublishedFundingVersionBulkInMemoryRepository, IVersionBulkRepository <PublishedFundingVersion> >();
            RegisterTypeAs <PublishedProviderDataGenerator, IPublishedProviderDataGenerator>();
            RegisterTypeAs <PublishedFundingStatusUpdateService, IPublishedFundingStatusUpdateService>();
            RegisterTypeAs <SpecificationFundingStatusService, ISpecificationFundingStatusService>();

            RegisterTypeAs <OrganisationGroupGenerator, IOrganisationGroupGenerator>();
            RegisterTypeAs <PublishedFundingChangeDetectorService, IPublishedFundingChangeDetectorService>();
            RegisterTypeAs <PublishedProviderVersionService, IPublishedProviderVersionService>();
            RegisterTypeAs <PublishedFundingInMemorySearchRepository, ISearchRepository <PublishedFundingIndex> >();

            RegisterTypeAs <GeneratePublishedFundingCsvJobCreation, ICreateGeneratePublishedFundingCsvJobs>();
            RegisterTypeAs <CreateGeneratePublishedProviderEstateCsvJobs, ICreateGeneratePublishedProviderEstateCsvJobs>();
            RegisterTypeAs <PublishIntegrityCheckJobCreation, ICreatePublishIntegrityJob>();
            RegisterTypeAs <CurrentCorrelationStepContext, ICurrentCorrelationStepContext>();

            IGeneratePublishedFundingCsvJobsCreation[] generatePublishedFundingCsvJobsCreations =
                typeof(IGeneratePublishedFundingCsvJobsCreation).Assembly.GetTypes()
                .Where(_ => _.Implements(typeof(IGeneratePublishedFundingCsvJobsCreation)) &&
                       !_.IsAbstract)
                .Select(_ => (IGeneratePublishedFundingCsvJobsCreation)Activator.CreateInstance(_,
                                                                                                ResolveInstance <ICreateGeneratePublishedFundingCsvJobs>(),
                                                                                                ResolveInstance <ICreateGeneratePublishedProviderEstateCsvJobs>()))
                .ToArray();
            RegisterInstanceAs <IGeneratePublishedFundingCsvJobsCreationLocator>(new GeneratePublishedFundingCsvJobsCreationLocator(generatePublishedFundingCsvJobsCreations));


            RegisterInstanceAs <IOrganisationGroupResiliencePolicies>(new OrganisationGroupResiliencePolicies
            {
                ProvidersApiClient = Policy.NoOpAsync()
            });

            RegisterTypeAs <OrganisationGroupTargetProviderLookup, IOrganisationGroupTargetProviderLookup>();

            IDetectPublishedProviderErrors[] detectorStrategies = typeof(PublishedProviderErrorDetector).Assembly.GetTypes()
                                                                  .Where(_ => _.Implements(typeof(PublishedProviderErrorDetector)))
                                                                  .Select(_ => (PublishedProviderErrorDetector)_objectContainer.Resolve(_))
                                                                  .ToArray();

            RegisterInstanceAs <IErrorDetectionStrategyLocator>(new ErrorDetectionStrategyLocator(detectorStrategies));
            RegisterTypeAs <PublishedProviderErrorDetection, IPublishedProviderErrorDetection>();

            PublishedProviderContentsGeneratorResolver providerContentsGeneratorResolver = new PublishedProviderContentsGeneratorResolver();

            providerContentsGeneratorResolver.Register("1.0", new PublishedProviderContentsGenerator());
            RegisterInstanceAs <IPublishedProviderContentsGeneratorResolver>(providerContentsGeneratorResolver);

            RegisterTypeAs <FundingLineTotalAggregator, IFundingLineTotalAggregator>();
            RegisterTypeAs <CalculationInMemoryRepository, ICalculationResultsRepository>();
            RegisterTypeAs <PublishedProviderStatusUpdateService, IPublishedProviderStatusUpdateService>();
            RegisterTypeAs <PublishedProviderStatusUpdateSettings, IPublishedProviderStatusUpdateSettings>();

            IVariationStrategy[] variationStrategies = typeof(IVariationStrategy).Assembly.GetTypes()
                                                       .Where(_ => _.Implements(typeof(IVariationStrategy)))
                                                       .Select(_ => (IVariationStrategy)_objectContainer.Resolve(_))
                                                       .ToArray();

            RegisterInstanceAs <IVariationStrategyServiceLocator>(new VariationStrategyServiceLocator(variationStrategies));

            RegisterTypeAs <ProviderVariationsDetection, IDetectProviderVariations>();
            RegisterTypeAs <SpecificationsInMemoryClient, ISpecificationsApiClient>();
            RegisterTypeAs <ProviderVariationsApplication, IApplyProviderVariations>();
            RegisterTypeAs <VariationServiceStepContext, IVariationServiceStepContext>();
            RegisterTypeAs <CalculationsInMemoryClient, ICalculationsApiClient>();
            RegisterTypeAs <CalculationPrerequisiteCheckerService, ICalculationPrerequisiteCheckerService>();
            RegisterTypeAs <JobsRunning, IJobsRunning>();
            RegisterTypeAs <SpecificationFundingStatusService, ISpecificationFundingStatusService>();
            RegisterTypeAs <CalculationPrerequisiteCheckerService, ICalculationPrerequisiteCheckerService>();
            RegisterTypeAs <RefreshPrerequisiteChecker, IPrerequisiteChecker>();
            RegisterTypeAs <PublishAllPrerequisiteChecker, IPrerequisiteChecker>();
            RegisterTypeAs <PublishBatchPrerequisiteChecker, IPrerequisiteChecker>();
            RegisterTypeAs <ApproveAllProvidersPrerequisiteChecker, IPrerequisiteChecker>();
            RegisterTypeAs <ApproveBatchProvidersPrerequisiteChecker, IPrerequisiteChecker>();

            IPrerequisiteChecker[] prerequisiteCheckers = typeof(IPrerequisiteChecker).Assembly.GetTypes()
                                                          .Where(_ => _.Implements(typeof(IPrerequisiteChecker)))
                                                          .Select(_ => (IPrerequisiteChecker)_objectContainer.Resolve(_))
                                                          .ToArray();

            RegisterInstanceAs <IPrerequisiteCheckerLocator>(new PrerequisiteCheckerLocator(prerequisiteCheckers));

            RegisterTypeAs <GenerateCsvJobsInMemoryClient, IGeneratePublishedFundingCsvJobsCreation>();

            PublishedFundingIdGeneratorResolver idGeneratorResolver = new PublishedFundingIdGeneratorResolver();

            idGeneratorResolver.Register("1.0", new PublishedFundingIdGenerator());
            RegisterTypeAs <PublishedFundingGenerator, IPublishedFundingGenerator>();

            RegisterInstanceAs <IPublishedFundingIdGeneratorResolver>(idGeneratorResolver);

            PublishedProviderContentsGeneratorResolver publishedProviderContentsGeneratorResolver = new PublishedProviderContentsGeneratorResolver();
            IPublishedProviderContentsGenerator        v10ProviderGenerator = new PublishedProviderContentsGenerator();

            publishedProviderContentsGeneratorResolver.Register("1.0", v10ProviderGenerator);

            RegisterInstanceAs <IPublishedProviderContentsGeneratorResolver>(publishedProviderContentsGeneratorResolver);

            PublishedFundingContentsGeneratorResolver publishedFundingContentsGeneratorResolver = new PublishedFundingContentsGeneratorResolver();
            IPublishedFundingContentsGenerator        v10Generator = new PublishedFundingContentsGenerator();

            publishedFundingContentsGeneratorResolver.Register("1.0", v10Generator);

            RegisterInstanceAs <IPublishedFundingContentsGeneratorResolver>(publishedFundingContentsGeneratorResolver);

            RegisterTypeAs <TransactionFactory, ITransactionFactory>();

            RegisterInstanceAs <ITransactionResiliencePolicies>(new TransactionResiliencePolicies
            {
                TransactionPolicy = Policy.NoOpAsync()
            });

            RegisterTypeAs <PublishedProviderIndexerService, IPublishedProviderIndexerService>();
            RegisterTypeAs <FundingLineValueOverride, IFundingLineValueOverride>();
            RegisterTypeAs <PublishedProviderDataPopulator, IPublishedProviderDataPopulator>();
            RegisterTypeAs <PublishedProviderExclusionCheck, IPublishProviderExclusionCheck>();
            RegisterTypeAs <PublishedProviderVersioningService, IPublishedProviderVersioningService>();
            RegisterTypeAs <PublishedProviderContentPersistanceService, IPublishedProviderContentPersistanceService>();
            RegisterTypeAs <PublishedFundingContentsPersistanceService, IPublishedFundingContentsPersistanceService>();

            RegisterTypeAs <VariationErrorRecorder, IRecordVariationErrors>();
            RegisterTypeAs <RefreshService, IRefreshService>();

            RegisterTypeAs <ApproveService, IApproveService>();

            RegisterTypeAs <PublishService, IPublishService>();

            RegisterInstanceAs <IBatchProfilingOptions>(new BatchProfilingOptions(new ConfigurationStub()));
            RegisterTypeAs <BatchProfilingService, IBatchProfilingService>();
            RegisterTypeAs <ProducerConsumerFactory, IProducerConsumerFactory>();

            RegisterInstanceAs <IFundingLineRoundingSettings>(new RoundingSettingsStub());
        }
Esempio n. 3
0
        private static IServiceProvider Register(IServiceCollection builder,
                                                 IConfigurationRoot config)
        {
            builder.AddSingleton <IFundingLineRoundingSettings, FundingLineRoundingSettings>();

            builder.AddSingleton <IBatchProfilingOptions, BatchProfilingOptions>();
            builder.AddSingleton <IBatchProfilingService, BatchProfilingService>();
            builder.AddSingleton <IProducerConsumerFactory, ProducerConsumerFactory>();

            builder.AddSingleton <IReProfilingResponseMapper, ReProfilingResponseMapper>();
            builder.AddSingleton <IReProfilingRequestBuilder, ReProfilingRequestBuilder>();

            builder.AddSingleton <IBatchUploadValidationService, BatchUploadValidationService>();
            builder.AddSingleton <IBatchUploadReaderFactory, BatchUploadReaderFactory>();
            builder.AddSingleton <IValidator <BatchUploadValidationRequest>, BatchUploadValidationRequestValidation>();

            ISqlSettings sqlSettings = new SqlSettings();

            config.Bind("saSql", sqlSettings);

            builder.AddSingleton(sqlSettings);

            builder.AddSingleton <ISqlPolicyFactory, SqlPolicyFactory>();
            builder.AddScoped <ISqlConnectionFactory, SqlConnectionFactory>();

            builder.AddScoped <IDataTableImporter, DataTableImporter>();
            builder.AddScoped <ISqlImportContextBuilder, SqlImportContextBuilder>();
            builder.AddScoped <ISqlImporter, SqlImporter>();
            builder.AddScoped <ISqlImportService, SqlImportService>();
            builder.AddScoped <ISqlNameGenerator, SqlNameGenerator>();
            builder.AddScoped <ISqlSchemaGenerator, SqlSchemaGenerator>();
            builder.AddScoped <IQaSchemaService, QaSchemaService>();
            builder.AddScoped <IQaRepository, QaRepository>();
            builder.AddSingleton <ITemplateMetadataResolver>(ctx =>
            {
                TemplateMetadataResolver resolver = new TemplateMetadataResolver();
                ILogger logger = ctx.GetService <ILogger>();

                TemplateMetadataSchema10.TemplateMetadataGenerator schema10Generator = new TemplateMetadataSchema10.TemplateMetadataGenerator(logger);
                resolver.Register("1.0", schema10Generator);

                TemplateMetadataSchema11.TemplateMetadataGenerator schema11Generator = new TemplateMetadataSchema11.TemplateMetadataGenerator(logger);
                resolver.Register("1.1", schema11Generator);

                return(resolver);
            });
            builder.AddSingleton <ICosmosRepository, CosmosRepository>();

            CosmosDbSettings settings = new CosmosDbSettings();

            config.Bind("CosmosDbSettings", settings);

            settings.ContainerName = "publishedfunding";

            builder.AddSingleton(settings);

            builder.AddSingleton <IUserProfileProvider, UserProfileProvider>();

            builder.AddFeatureManagement();

            builder.AddSingleton <IConfiguration>(ctx => config);
            builder
            .AddScoped <IPublishedFundingQueryBuilder, PublishedFundingQueryBuilder>();

            builder
            .AddSingleton <IPublishingEngineOptions>(_ => new PublishingEngineOptions(config));

            builder.AddSingleton <IPublishedFundingRepository, PublishedFundingRepository>((ctx) =>
            {
                CosmosDbSettings calssDbSettings = new CosmosDbSettings();

                config.Bind("CosmosDbSettings", calssDbSettings);

                calssDbSettings.ContainerName = "publishedfunding";

                CosmosRepository calcsCosmosRepostory = new CosmosRepository(calssDbSettings);
                IPublishedFundingQueryBuilder publishedFundingQueryBuilder = ctx.GetService <IPublishedFundingQueryBuilder>();

                return(new PublishedFundingRepository(calcsCosmosRepostory, publishedFundingQueryBuilder));
            });

            builder.AddSingleton <IPublishedFundingBulkRepository, PublishedFundingBulkRepository>((ctx) =>
            {
                CosmosDbSettings settings = new CosmosDbSettings();

                config.Bind("CosmosDbSettings", settings);

                settings.ContainerName = "publishedfunding";

                IPublishingEngineOptions publishingEngineOptions = ctx.GetService <IPublishingEngineOptions>();

                CosmosRepository calcsCosmosRepository = new CosmosRepository(settings, publishingEngineOptions.AllowBatching ? new CosmosClientOptions
                {
                    ConnectionMode = ConnectionMode.Direct,
                    RequestTimeout = new TimeSpan(0, 0, 15),
                    MaxRequestsPerTcpConnection  = publishingEngineOptions.MaxRequestsPerTcpConnectionPublishedFundingCosmosBulkOptions,
                    MaxTcpConnectionsPerEndpoint = publishingEngineOptions.MaxTcpConnectionsPerEndpointPublishedFundingCosmosBulkOptions,
                    ConsistencyLevel             = ConsistencyLevel.Eventual,
                    AllowBulkExecution           = true
                } : null);

                IPublishingResiliencePolicies publishingResiliencePolicies = ctx.GetService <IPublishingResiliencePolicies>();

                return(new PublishedFundingBulkRepository(publishingResiliencePolicies, publishingEngineOptions, calcsCosmosRepository));
            });

            CosmosDbSettings publishedfundingCosmosSettings = new CosmosDbSettings();

            config.Bind("CosmosDbSettings", publishedfundingCosmosSettings);

            publishedfundingCosmosSettings.ContainerName = "publishedfunding";

            builder.AddSingleton(publishedfundingCosmosSettings);
            builder.AddSingleton <ICosmosRepository, CosmosRepository>();
            builder.AddCaching(config);
            builder.AddSearch(config);
            builder
            .AddSingleton <ISearchRepository <PublishedProviderIndex>, SearchRepository <PublishedProviderIndex> >();
            builder
            .AddSingleton <ISearchRepository <PublishedFundingIndex>, SearchRepository <PublishedFundingIndex> >();

            // These registrations of the functions themselves are just for the DebugQueue. Ideally we don't want these registered in production
            if (Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") == "Development")
            {
                builder.AddScoped(_ => new OnRefreshFunding(_.GetService <ILogger>(),
                                                            _.GetService <IRefreshService>(),
                                                            _.GetService <IMessengerService>(),
                                                            _.GetService <IUserProfileProvider>(),
                                                            true));
                builder.AddScoped(_ => new OnApproveAllProviderFunding(_.GetService <ILogger>(),
                                                                       _.GetService <IApproveService>(),
                                                                       _.GetService <IMessengerService>(),
                                                                       _.GetService <IUserProfileProvider>(),
                                                                       true));
                builder.AddScoped(_ => new OnPublishAllProviderFunding(_.GetService <ILogger>(),
                                                                       _.GetService <IPublishService>(),
                                                                       _.GetService <IMessengerService>(),
                                                                       _.GetService <IUserProfileProvider>(),
                                                                       true));
                builder.AddScoped <OnRunSqlImport>();
                builder.AddScoped <OnRefreshFundingFailure>();
                builder.AddScoped <OnApproveAllProviderFundingFailure>();
                builder.AddScoped <OnPublishAllProviderFundingFailure>();
                builder.AddScoped <OnPublishIntegrityCheck>();
                builder.AddScoped <OnPublishIntegrityCheckFailure>();
                builder.AddScoped <OnDeletePublishedProviders>();
                builder.AddScoped <OnDeletePublishedProvidersFailure>();
                builder.AddScoped <OnReIndexPublishedProviders>();
                builder.AddScoped <OnGeneratePublishedFundingCsv>();
                builder.AddScoped <OnGeneratePublishedFundingCsvFailure>();
                builder.AddScoped <OnGeneratePublishedProviderEstateCsv>();
                builder.AddScoped <OnGeneratePublishedProviderEstateCsvFailure>();
                builder.AddScoped(_ => new OnApproveBatchProviderFunding(_.GetService <ILogger>(),
                                                                         _.GetService <IApproveService>(),
                                                                         _.GetService <IMessengerService>(),
                                                                         _.GetService <IUserProfileProvider>(),
                                                                         true));
                builder.AddScoped <OnApproveBatchProviderFundingFailure>();
                builder.AddScoped(_ => new OnPublishBatchProviderFunding(_.GetService <ILogger>(),
                                                                         _.GetService <IPublishService>(),
                                                                         _.GetService <IMessengerService>(),
                                                                         _.GetService <IUserProfileProvider>(),
                                                                         true));
                builder.AddScoped <OnPublishBatchProviderFundingFailure>();
                builder.AddScoped <OnPublishedFundingUndo>();
                builder.AddScoped <OnBatchPublishedProviderValidation>();
                builder.AddScoped <OnBatchPublishedProviderValidationFailure>();
            }

            builder.AddSingleton <ISpecificationService, SpecificationService>();
            builder.AddSingleton <IProviderService, ProviderService>();
            builder.AddSingleton <IPublishedFundingService, PublishedFundingService>();
            builder.AddSingleton <IPoliciesService, PoliciesService>();
            builder.AddSingleton <IPublishedFundingVersionDataService, PublishedFundingVersionDataService>();

            builder.AddScoped <IRefreshService, RefreshService>();
            builder.AddScoped <IVariationService, VariationService>();
            builder.AddTransient <IRecordVariationErrors, VariationErrorRecorder>();
            builder.AddTransient <IApplyProviderVariations, ProviderVariationsApplication>();
            builder.AddTransient <IDetectProviderVariations, ProviderVariationsDetection>();
            builder.AddTransient <IVariationStrategyServiceLocator, VariationStrategyServiceLocator>();
            builder.AddTransient <IVariationStrategy, ClosureVariationStrategy>();
            builder.AddTransient <IVariationStrategy, ClosureWithSuccessorVariationStrategy>();
            builder.AddTransient <IVariationStrategy, ProviderMetadataVariationStrategy>();
            builder.AddTransient <IVariationStrategy, PupilNumberSuccessorVariationStrategy>();
            builder.AddTransient <IVariationStrategy, FundingUpdatedVariationStrategy>();
            builder.AddTransient <IVariationStrategy, ProfilingUpdatedVariationStrategy>();
            builder.AddTransient <IVariationStrategy, DsgTotalAllocationChangeVariationStrategy>();
            builder.AddTransient <IVariationStrategy, ReProfilingVariationStrategy>();
            builder.AddSingleton <IReProfilingResponseMapper, ReProfilingResponseMapper>();
            builder.AddScoped <IApproveService, ApproveService>();
            builder.AddSingleton <IJobTracker, JobTracker>();
            builder.AddScoped <IPublishService, PublishService>();
            builder.AddSingleton <IJobManagement, JobManagement>();
            builder.AddSingleton <ISpecificationFundingStatusService, SpecificationFundingStatusService>();
            builder.AddScoped <ICsvUtils, CsvUtils>();
            builder.AddSingleton <IFileSystemAccess, FileSystemAccess>();
            builder.AddSingleton <IFileSystemCacheSettings, FileSystemCacheSettings>();
            builder.AddScoped <IReApplyCustomProfiles, ReApplyCustomProfiles>();
            builder.AddScoped <IPublishedProviderErrorDetection, PublishedProviderErrorDetection>();
            builder.AddTransient <IErrorDetectionStrategyLocator, ErrorDetectionStrategyLocator>();
            builder.AddTransient <IDetectPublishedProviderErrors, FundingLineValueProfileMismatchErrorDetector>();
            builder.AddTransient <IDetectPublishedProviderErrors, TrustIdMismatchErrorDetector>();

            builder.AddScoped <IGeneratePublishedFundingCsvJobsCreationLocator, GeneratePublishedFundingCsvJobsCreationLocator>();
            builder.AddScoped <IGeneratePublishedFundingCsvJobsCreation, GenerateRefreshPublishedFundingCsvJobsCreation>();
            builder.AddScoped <IGeneratePublishedFundingCsvJobsCreation, GenerateApprovePublishedFundingCsvJobsCreation>();
            builder.AddScoped <IGeneratePublishedFundingCsvJobsCreation, GenerateReleasePublishedFundingCsvJobsCreation>();

            builder.AddScoped <IFundingLineCsvGenerator, FundingLineCsvGenerator>();
            builder.AddScoped <IFundingLineCsvTransform, PublishedProviderFundingLineCsvTransform>();
            builder.AddScoped <IFundingLineCsvTransform, PublishedProviderVersionFundingLineCsvTransform>();
            builder.AddScoped <IFundingLineCsvTransform, PublishedProviderDeliveryProfileFundingLineCsvTransform>();
            builder.AddScoped <IFundingLineCsvTransform, PublishedProviderVersionFundingLineProfileValuesCsvTransform>();
            builder.AddScoped <IFundingLineCsvTransform, PublishedFundingFundingLineGroupingCsvTransform>();
            builder.AddScoped <IFundingLineCsvTransform, PublishedFundingVersionFundingLineGroupingCsvTransform>();
            builder.AddScoped <IFundingLineCsvTransform, PublishedGroupsFundingLineCsvTransform>();

            builder.AddScoped <IFundingLineCsvTransformServiceLocator, FundingLineCsvTransformServiceLocator>();
            builder.AddScoped <IPublishedFundingPredicateBuilder, PublishedFundingPredicateBuilder>();

            builder.AddScoped <IFundingLineCsvBatchProcessorServiceLocator, FundingLineCsvBatchProcessorServiceLocator>();
            builder.AddScoped <IFundingLineCsvBatchProcessor, PublishedProviderCsvBatchProcessor>();
            builder.AddScoped <IFundingLineCsvBatchProcessor, PublishedProviderVersionCsvBatchProcessor>();
            builder.AddScoped <IFundingLineCsvBatchProcessor, PublishedFundingOrganisationGroupCsvBatchProcessor>();
            builder.AddScoped <IFundingLineCsvBatchProcessor, PublishedFundingVersionOrganisationGroupCsvBatchProcessor>();
            builder.AddScoped <IFundingLineCsvBatchProcessor, PublishedGroupsCsvBatchProcessor>();

            builder.AddTransient <ICreateGeneratePublishedFundingCsvJobs, GeneratePublishedFundingCsvJobCreation>();
            builder.AddScoped <IPublishedProviderEstateCsvGenerator, PublishedProviderEstateCsvGenerator>()
            .AddSingleton <IHealthChecker, PublishedProviderEstateCsvGenerator>();
            builder.AddScoped <IPublishedProviderCsvTransformServiceLocator, PublishedProviderCsvTransformServiceLocator>();
            builder.AddScoped <IPublishedProviderCsvTransform, PublishedProviderEstateCsvTransform>();
            builder.AddScoped <ICreateGeneratePublishedProviderEstateCsvJobs, CreateGeneratePublishedProviderEstateCsvJobs>();

            builder
            .AddSingleton <IPublishedProviderVersioningService, PublishedProviderVersioningService>()
            .AddSingleton <IHealthChecker, PublishedProviderVersioningService>();

            builder
            .AddSingleton <IPublishedProviderStatusUpdateService, PublishedProviderStatusUpdateService>()
            .AddSingleton <IHealthChecker, PublishedProviderStatusUpdateService>();

            builder
            .AddSingleton <IPublishedProviderVersionService, PublishedProviderVersionService>()
            .AddSingleton <IHealthChecker, PublishedProviderVersionService>();

            builder
            .AddSingleton <IPublishedSearchService, PublishedSearchService>()
            .AddSingleton <IHealthChecker, PublishedSearchService>();
            builder
            .AddSingleton <IPublishedProviderStatusUpdateSettings>(_ =>
            {
                PublishedProviderStatusUpdateSettings settings = new PublishedProviderStatusUpdateSettings();

                config.Bind("PublishedProviderStatusUpdateSettings", settings);

                return(settings);
            }
                                                                   );

            builder
            .AddSingleton <Common.Storage.IBlobClient, CommonBlobClient>((ctx) =>
            {
                BlobStorageOptions storageSettings = new BlobStorageOptions();

                config.Bind("AzureStorageSettings", storageSettings);

                storageSettings.ContainerName = "publishedproviderversions";

                IBlobContainerRepository blobContainerRepository = new BlobContainerRepository(storageSettings);
                return(new CommonBlobClient(blobContainerRepository));
            });

            builder
            .AddSingleton <IBlobClient, BlobClient>((ctx) =>
            {
                AzureStorageSettings storageSettings = new AzureStorageSettings();

                config.Bind("AzureStorageSettings", storageSettings);

                storageSettings.ContainerName = "publishedproviderversions";

                return(new BlobClient(storageSettings));
            });

            builder.AddSingleton <IVersionRepository <PublishedProviderVersion>, VersionRepository <PublishedProviderVersion> >((ctx) =>
            {
                CosmosDbSettings publishedProviderVersioningDbSettings = new CosmosDbSettings();

                config.Bind("CosmosDbSettings", publishedProviderVersioningDbSettings);

                publishedProviderVersioningDbSettings.ContainerName = "publishedfunding";

                CosmosRepository resultsRepostory = new CosmosRepository(publishedProviderVersioningDbSettings);

                return(new VersionRepository <PublishedProviderVersion>(resultsRepostory, new NewVersionBuilderFactory <PublishedProviderVersion>()));
            });

            builder.AddSingleton <IVersionBulkRepository <PublishedProviderVersion>, VersionBulkRepository <PublishedProviderVersion> >((ctx) =>
            {
                CosmosDbSettings PublishedProviderVersioningDbSettings = new CosmosDbSettings();

                config.Bind("CosmosDbSettings", PublishedProviderVersioningDbSettings);

                PublishedProviderVersioningDbSettings.ContainerName = "publishedfunding";

                IPublishingEngineOptions publishingEngineOptions = ctx.GetService <IPublishingEngineOptions>();

                CosmosRepository cosmosRepository = new CosmosRepository(PublishedProviderVersioningDbSettings, publishingEngineOptions.AllowBatching ? new CosmosClientOptions
                {
                    ConnectionMode = ConnectionMode.Direct,
                    RequestTimeout = new TimeSpan(0, 0, 15),
                    MaxRequestsPerTcpConnection  = publishingEngineOptions.MaxRequestsPerTcpConnectionPublishedFundingCosmosBulkOptions,
                    MaxTcpConnectionsPerEndpoint = publishingEngineOptions.MaxTcpConnectionsPerEndpointPublishedFundingCosmosBulkOptions,
                    ConsistencyLevel             = ConsistencyLevel.Eventual,
                    AllowBulkExecution           = true
                } : null);

                return(new VersionBulkRepository <PublishedProviderVersion>(cosmosRepository, new NewVersionBuilderFactory <PublishedProviderVersion>()));
            });

            builder.AddSingleton <IVersionRepository <PublishedFundingVersion>, VersionRepository <PublishedFundingVersion> >((ctx) =>
            {
                CosmosDbSettings ProviderSourceDatasetVersioningDbSettings = new CosmosDbSettings();

                config.Bind("CosmosDbSettings", ProviderSourceDatasetVersioningDbSettings);

                ProviderSourceDatasetVersioningDbSettings.ContainerName = "publishedfunding";

                CosmosRepository cosmosRepository = new CosmosRepository(ProviderSourceDatasetVersioningDbSettings);

                return(new VersionRepository <PublishedFundingVersion>(cosmosRepository, new NewVersionBuilderFactory <PublishedFundingVersion>()));
            });

            builder.AddSingleton <IVersionBulkRepository <PublishedFundingVersion>, VersionBulkRepository <PublishedFundingVersion> >((ctx) =>
            {
                CosmosDbSettings PublishedFundingVersioningDbSettings = new CosmosDbSettings();

                config.Bind("CosmosDbSettings", PublishedFundingVersioningDbSettings);

                PublishedFundingVersioningDbSettings.ContainerName = "publishedfunding";

                IPublishingEngineOptions publishingEngineOptions = ctx.GetService <IPublishingEngineOptions>();

                CosmosRepository cosmosRepository = new CosmosRepository(PublishedFundingVersioningDbSettings, publishingEngineOptions.AllowBatching ? new CosmosClientOptions
                {
                    ConnectionMode = ConnectionMode.Direct,
                    RequestTimeout = new TimeSpan(0, 0, 15),
                    MaxRequestsPerTcpConnection  = publishingEngineOptions.MaxRequestsPerTcpConnectionPublishedFundingCosmosBulkOptions,
                    MaxTcpConnectionsPerEndpoint = publishingEngineOptions.MaxTcpConnectionsPerEndpointPublishedFundingCosmosBulkOptions,
                    ConsistencyLevel             = ConsistencyLevel.Eventual,
                    AllowBulkExecution           = true
                } : null);

                return(new VersionBulkRepository <PublishedFundingVersion>(cosmosRepository, new NewVersionBuilderFactory <PublishedFundingVersion>()));
            });


            builder.AddSingleton <ICalculationResultsRepository, CalculationResultsRepository>((ctx) =>
            {
                CosmosDbSettings calssDbSettings = new CosmosDbSettings();

                config.Bind("CosmosDbSettings", calssDbSettings);

                calssDbSettings.ContainerName = "calculationresults";

                IPublishingEngineOptions publishingEngineOptions = ctx.GetService <IPublishingEngineOptions>();

                CosmosRepository calcsCosmosRepository = new CosmosRepository(calssDbSettings, new CosmosClientOptions
                {
                    ConnectionMode = ConnectionMode.Direct,
                    RequestTimeout = new TimeSpan(0, 0, 15),
                    MaxRequestsPerTcpConnection  = publishingEngineOptions.MaxRequestsPerTcpConnectionCalculationsCosmosBulkOptions,
                    MaxTcpConnectionsPerEndpoint = publishingEngineOptions.MaxTcpConnectionsPerEndpointCalculationsCosmosBulkOptions,
                    ConsistencyLevel             = ConsistencyLevel.Eventual,
                    AllowBulkExecution           = true
                });

                return(new CalculationResultsRepository(calcsCosmosRepository));
            });

            builder.AddSingleton <ICalculationResultsService, CalculationResultsService>();

            builder.AddSingleton <IPublishedProviderDataGenerator, PublishedProviderDataGenerator>();

            builder.AddSingleton <IFundingLineTotalAggregator, FundingLineTotalAggregator>();

            builder
            .AddSingleton <IProfilingService, ProfilingService>()
            .AddSingleton <IHealthChecker, ProfilingService>();

            builder.AddSingleton(new MapperConfiguration(_ =>
            {
                _.AddProfile <PublishingServiceMappingProfile>();
            }).CreateMapper());

            builder.AddSingleton <IPublishedProviderDataPopulator, PublishedProviderDataPopulator>();

            builder.AddSingleton <IPublishIntegrityCheckService, PublishIntegrityCheckService>();

            builder.AddSingleton <IPublishedProviderContentsGeneratorResolver>(ctx =>
            {
                PublishedProviderContentsGeneratorResolver resolver = new PublishedProviderContentsGeneratorResolver();

                resolver.Register("1.0", new Generators.Schema10.PublishedProviderContentsGenerator());
                resolver.Register("1.1", new Generators.Schema11.PublishedProviderContentsGenerator());

                return(resolver);
            });

            builder.AddSingleton <IPublishedFundingContentsGeneratorResolver>(ctx =>
            {
                PublishedFundingContentsGeneratorResolver resolver = new PublishedFundingContentsGeneratorResolver();

                resolver.Register("1.0", new Generators.Schema10.PublishedFundingContentsGenerator());
                resolver.Register("1.1", new Generators.Schema11.PublishedFundingContentsGenerator());

                return(resolver);
            });

            builder.AddSingleton <IPublishedFundingIdGeneratorResolver>(ctx =>
            {
                PublishedFundingIdGeneratorResolver resolver = new PublishedFundingIdGeneratorResolver();

                IPublishedFundingIdGenerator v10Generator = new Generators.Schema10.PublishedFundingIdGenerator();

                resolver.Register("1.0", v10Generator);
                resolver.Register("1.1", v10Generator);

                return(resolver);
            });

            builder.AddSingleton <IDeadletterService, DeadletterService>();

            builder.AddSingleton <IPublishedProviderReIndexerService, PublishedProviderReIndexerService>();

            builder.AddApplicationInsightsServiceName(config, "CalculateFunding.Functions.Publishing");

            builder.AddLogging("CalculateFunding.Functions.Publishing", config);

            builder.AddTelemetry();

            PolicySettings     policySettings = ServiceCollectionExtensions.GetPolicySettings(config);
            ResiliencePolicies publishingResiliencePolicies = CreateResiliencePolicies(policySettings);

            builder.AddSingleton <IJobManagementResiliencePolicies>((ctx) =>
            {
                AsyncBulkheadPolicy totalNetworkRequestsPolicy = ResiliencePolicyHelpers.GenerateTotalNetworkRequestsPolicy(policySettings);

                return(new JobManagementResiliencePolicies()
                {
                    JobsApiClient = ResiliencePolicyHelpers.GenerateRestRepositoryPolicy(totalNetworkRequestsPolicy)
                });
            });

            builder.AddServiceBus(config, "publishing");

            builder.AddPublishingServices(config);

            builder.AddSingleton <IPublishingResiliencePolicies>(publishingResiliencePolicies);

            builder.AddSpecificationsInterServiceClient(config, handlerLifetime: Timeout.InfiniteTimeSpan);
            builder.AddProvidersInterServiceClient(config, handlerLifetime: Timeout.InfiniteTimeSpan);

            builder.AddJobsInterServiceClient(config, handlerLifetime: Timeout.InfiniteTimeSpan);
            builder.AddCalculationsInterServiceClient(config, handlerLifetime: Timeout.InfiniteTimeSpan);
            builder.AddPoliciesInterServiceClient(config, handlerLifetime: Timeout.InfiniteTimeSpan);
            builder.AddFundingDataServiceInterServiceClient(config, handlerLifetime: Timeout.InfiniteTimeSpan);

            builder.AddSingleton <ITransactionResiliencePolicies>((ctx) => new TransactionResiliencePolicies()
            {
                TransactionPolicy = ResiliencePolicyHelpers.GenerateTotalNetworkRequestsPolicy(policySettings)
            });

            builder.AddSingleton <ITransactionFactory, TransactionFactory>();

            builder
            .AddProfilingInterServiceClient(config, handlerLifetime: Timeout.InfiniteTimeSpan);

            builder.AddScoped <IPublishedFundingUndoJobService, PublishedFundingUndoJobService>();
            builder.AddScoped <IPublishedFundingUndoJobCreation, PublishedFundingUndoJobCreation>();
            builder.AddScoped <IPublishedFundingUndoTaskFactoryLocator, PublishedFundingUndoTaskFactoryLocator>();
            builder.AddSingleton <IPublishedFundingUndoTaskFactory, SoftDeletePublishedFundingUndoTaskFactory>();
            builder.AddSingleton <IPublishedFundingUndoTaskFactory, HardDeletePublishedFundingUndoTaskFactory>();
            builder.AddSingleton <IPublishedFundingUndoCosmosRepository>(ctx =>
            {
                CosmosDbSettings settings = new CosmosDbSettings();

                config.Bind("CosmosDbSettings", settings);

                settings.ContainerName = "publishedfunding";

                return(new PublishedFundingUndoCosmosRepository(ctx.GetService <IPublishingResiliencePolicies>(),
                                                                new CosmosRepository(settings)));
            });
            builder.AddSingleton <IPublishedFundingUndoBlobStoreRepository>(ctx =>
            {
                BlobStorageOptions settings = new BlobStorageOptions();

                config.Bind("AzureStorageSettings", settings);

                settings.ContainerName = "publishedproviderversions";

                IBlobContainerRepository blobContainerRepository = new BlobContainerRepository(settings);
                return(new PublishedFundingUndoBlobStoreRepository(new CommonBlobClient(blobContainerRepository),
                                                                   ctx.GetService <IPublishingResiliencePolicies>(),
                                                                   ctx.GetService <ILogger>()));
            });

            builder.AddSingleton <IProducerConsumerFactory, ProducerConsumerFactory>();

            builder.AddScoped <IUserProfileProvider, UserProfileProvider>();

            return(builder.BuildServiceProvider());
        }