public AppInsightBlobSink(
            ITelemetryProcessor next,
            IConfiguration config,
            IConfiguration schemaConfig,
            ILogger logger,
            IEnumerable <CloudBlobClient> blobClients,
            Func <CloudBlockBlob, Task> onBlobWrittenFunc,
            Func <string> containerNameFunc,
            string dataSource,
            string fileType)
            : base(config, logger, blobClients, onBlobWrittenFunc, containerNameFunc, dataSource, fileType)
        {
            _next = next;

            // Reflection: Create Instance of ITransformOpenSchema
            TransformConfig openSchemaConfig = new TransformConfig();

            schemaConfig.Bind(openSchemaConfig);
            var factoryType = Type.GetType(openSchemaConfig.TransformOutput.ClassAssembly, throwOnError: true);

            _transform  = Activator.CreateInstance(factoryType) as ITransformOutput;
            _dataSource = dataSource;
        }
        private static async Task <bool> PublishOpenSchemaToBlobStorage(
            IConfiguration config,
            ILogger logger,
            TelemetryProcessorChainBuilder aiClientBuilder)
        {
            // AppInsights Config
            var appInsightsLoggingConfig = new AppInsightBlobConfig();

            config.Bind(appInsightsLoggingConfig);

            // Notification endpoint for Blobs to be read by AppInsights OpenSchema
            Uri blobNotificationEndpoint = null;

            if (!string.IsNullOrEmpty(appInsightsLoggingConfig.BlobNotificationEndpoint))
            {
                blobNotificationEndpoint = new Uri(appInsightsLoggingConfig.BlobNotificationEndpoint);
            }

            // Blob and OpenSchema Config
            var           blobConfigSection     = config.GetSection(AppInsightBlobConfig.BlobPublisherSection);
            List <string> storageAccountStrings = new List <string>();

            blobConfigSection.GetSection(AppInsightBlobConfig.StorageAccountsSection).Bind(storageAccountStrings);

            string fileType          = blobConfigSection.GetValue <string>(AppInsightBlobConfig.FileTypeValue, AppInsightBlobConfig.JSONFileType);
            var    baseContainerName = blobConfigSection.GetValue <string>(AppInsightBlobConfig.BaseContainerNameValue);

            List <CloudStorageAccount> storageAccounts = storageAccountStrings.Select(CloudStorageAccount.Parse).ToList();

            // Exit if no storage accounts in config
            if (storageAccounts.Count == 0)
            {
                logger?.LogWarning($"{nameof(PublishOpenSchemaToBlobStorage)} No Storage Accounts found in config.");
                return(false);
            }

            var blobClients = storageAccounts.Select(s => s.CreateCloudBlobClient()).ToList();

            var schemaNameConfig = config.GetSection(AppInsightBlobConfig.SchemaIdListSection);

            foreach (var dataSourceSchemaId in schemaNameConfig.GetChildren())
            {
                string          dataSourceName   = dataSourceSchemaId.Key;
                TransformConfig openSchemaConfig = new TransformConfig();
                dataSourceSchemaId.Bind(openSchemaConfig);

                Func <CloudBlockBlob, Task> OpenSchemaCallbackFunc = async(blob) =>
                {
                    await OpenSchemaCallback.PostCallback(
                        logger : logger,
                        blob : blob,
                        endpoint : blobNotificationEndpoint,
                        schemaName : openSchemaConfig.Id,
                        iKey : appInsightsLoggingConfig.InstrumentationKey);
                };

                // Blob publisher
                aiClientBuilder.Use(
                    (next) =>
                    new AppInsightBlobSink(
                        next: next,
                        config: config,
                        schemaConfig: dataSourceSchemaId,
                        logger: logger,
                        dataSource: dataSourceName,
                        fileType: fileType,
                        blobClients: blobClients,
                        onBlobWrittenFunc: OpenSchemaCallbackFunc,
                        // Use a naming function that promotes differences in the start of the name to improve storage paritioning
                        containerNameFunc: () =>
                {
                    var date = DateTime.UtcNow.ToString("yyyy-MM-dd-HH");
                    return($"{GetHashPrefix(date, 5)}-{baseContainerName}-{date}");
                })
                    );
            }

            return(await Task.FromResult(true));
        }