static void Main(string[] args)
 {
     Options options = new Options();
     if (CommandLine.Parser.Default.ParseArguments(args, options))
     {
         _isVerbose = options.Verbose;
         ConsoleColor oldColor = Console.ForegroundColor;
         try
         {
             AsyncContext.Run(() => AsyncMain(options));
         }
         catch (ConsoleAppException ex)
         {
             Console.WriteLine(ex.Message);
         }
         finally
         {
             Console.ForegroundColor = oldColor;
         }
     }
 }
        private static async Task AsyncMain(Options options)
        {
            WriteVerbose($"Processing configuration file {options.Configuration}");
            if (!File.Exists(options.Configuration))
            {
                throw new ConsoleAppException("Configuration file does not exist");
            }

            IDependencyResolver dependencyResolver = new UnityApplicationFrameworkDependencyResolver(new UnityContainer());
            dependencyResolver.UseCore().UseAzure();

            bool useKeyVault = !string.IsNullOrWhiteSpace(options.KeyVaultClientId) && !string.IsNullOrWhiteSpace(options.KeyVaultClientKey) && !string.IsNullOrWhiteSpace(options.KeyVaultUri);
            IAsyncConfiguration keyVaultConfiguration = null;
            if (useKeyVault)
            {
                dependencyResolver.UseAsyncKeyVaultApplicationConfiguration(options.KeyVaultClientId, options.KeyVaultClientKey, options.KeyVaultUri);
                keyVaultConfiguration = dependencyResolver.Resolve<IAsyncKeyVaultConfiguration>();
                WriteVerbose($"Using key vault {options.KeyVaultUri}");
            }

            WriteVerbose("Reading settings");
            string[] settingsFiles = options.Settings.Split(',');
            ApplicationConfigurationSettings settings = ApplicationConfigurationSettings.FromFiles(settingsFiles);            
            WriteVerbose("Reading configuration");
            ApplicationConfiguration configuration = await ApplicationConfiguration.FromFileAsync(options.Configuration, settings,
                options.CheckForMissingSettings, keyVaultConfiguration, WriteVerbose);

            ApplyCorsRules(configuration);

            foreach (ApplicationComponent component in configuration.ApplicationComponents)
            {
                if (component.UsesServiceBus)
                {
                    WriteVerbose($"Creating service bus resources for component {component.Fqn}");
                    if (!String.IsNullOrWhiteSpace(component.DefaultTopicName))
                    {
                        NamespaceManager namespaceManager =
                            NamespaceManager.CreateFromConnectionString(component.ServiceBusConnectionString);

                        if (!namespaceManager.TopicExists(component.DefaultTopicName))
                        {
                            namespaceManager.CreateTopic(new TopicDescription(component.DefaultTopicName));
                        }

                        if (!String.IsNullOrWhiteSpace(component.DefaultSubscriptionName))
                        {
                            if (
                                !namespaceManager.SubscriptionExists(component.DefaultTopicName,
                                    component.DefaultSubscriptionName))
                            {
                                namespaceManager.CreateSubscription(
                                    new SubscriptionDescription(component.DefaultTopicName,
                                        component.DefaultSubscriptionName));
                            }
                        }
                    }

                    if (!String.IsNullOrWhiteSpace(component.DefaultBrokeredMessageQueueName))
                    {
                        NamespaceManager namespaceManager =
                            NamespaceManager.CreateFromConnectionString(component.ServiceBusConnectionString);
                        if (!namespaceManager.QueueExists(component.DefaultBrokeredMessageQueueName))
                        {
                            namespaceManager.CreateQueue(component.DefaultBrokeredMessageQueueName);
                        }
                    }

                    foreach (ApplicationComponentSetting setting in component.Settings)
                    {
                        string resourceType = setting.ResourceType;
                        if (resourceType != null)
                        {
                            resourceType = resourceType.ToLower();
                            if (resourceType == "topic")
                            {
                                NamespaceManager namespaceManager =
                                    NamespaceManager.CreateFromConnectionString(component.ServiceBusConnectionString);
                                if (!namespaceManager.TopicExists(setting.Value))
                                {
                                    namespaceManager.CreateTopic(new TopicDescription(setting.Value));
                                }
                            }
                            else if (resourceType == "subscription")
                            {
                                NamespaceManager namespaceManager =
                                    NamespaceManager.CreateFromConnectionString(component.ServiceBusConnectionString);
                                string topicPath = setting.Attributes["topic"];
                                if (!namespaceManager.TopicExists(topicPath))
                                {
                                    namespaceManager.CreateTopic(new TopicDescription(topicPath));
                                }
                                if (!namespaceManager.SubscriptionExists(topicPath, setting.Value))
                                {
                                    namespaceManager.CreateSubscription(new SubscriptionDescription(topicPath,
                                        setting.Value));
                                }
                            }
                            else if (resourceType == "brokered-message-queue")
                            {
                                NamespaceManager namespaceManager =
                                    NamespaceManager.CreateFromConnectionString(component.ServiceBusConnectionString);
                                if (!namespaceManager.QueueExists(setting.Value))
                                {
                                    namespaceManager.CreateQueue(setting.Value);
                                }
                            }
                        }
                    }
                }

                if (component.UsesAzureStorage)
                {
                    CloudStorageAccount storageAccount =
                        CloudStorageAccount.Parse(component.StorageAccountConnectionString);
                    if (!string.IsNullOrWhiteSpace(component.DefaultBlobContainerName))
                    {
                        CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
                        CloudBlobContainer blobContainer =
                            blobClient.GetContainerReference(component.DefaultBlobContainerName);
                        blobContainer.CreateIfNotExists(
                            BlobContainerPublicAccessType(component.DefaultBlobContainerAccessType));

                        WriteVerbose($"Creating blob container {component.DefaultBlobContainerName} in {storageAccount.BlobEndpoint}");

                        if (component.Uploads != null)
                        {
                            foreach (string uploadFilename in component.Uploads)
                            {
                                string fullUploadFilename = Path.Combine(Path.GetDirectoryName(options.Configuration),
                                    uploadFilename);
                                CloudBlockBlob blob =
                                    blobContainer.GetBlockBlobReference(Path.GetFileName(uploadFilename));
                                blob.UploadFromFile(fullUploadFilename, FileMode.Open);
                                WriteVerbose($"Uploading file {uploadFilename} to blob container {component.DefaultBlobContainerName}");
                            }
                        }
                    }

                    if (!string.IsNullOrWhiteSpace(component.DefaultLeaseBlockName))
                    {
                        CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
                        CloudBlobContainer blobContainer =
                            blobClient.GetContainerReference(component.DefaultLeaseBlockName);
                        blobContainer.CreateIfNotExists(
                            BlobContainerPublicAccessType(component.DefaultBlobContainerAccessType));

                        WriteVerbose($"Creating lease block container {component.DefaultLeaseBlockName} in {storageAccount.BlobEndpoint}");
                    }

                    if (!string.IsNullOrWhiteSpace(component.DefaultQueueName))
                    {
                        CloudQueueClient queueClient = storageAccount.CreateCloudQueueClient();
                        CloudQueue queue = queueClient.GetQueueReference(component.DefaultQueueName);
                        queue.CreateIfNotExists();

                        WriteVerbose($"Creating queue {component.DefaultQueueName} in {storageAccount.QueueEndpoint}");
                    }

                    if (!string.IsNullOrWhiteSpace(component.DefaultTableName))
                    {
                        CloudTableClient tableClient = storageAccount.CreateCloudTableClient();
                        CloudTable table = tableClient.GetTableReference(component.DefaultTableName);
                        table.CreateIfNotExists();

                        WriteVerbose($"Creating table {component.DefaultTableName} in {storageAccount.TableEndpoint}");

                        if (!string.IsNullOrWhiteSpace(component.TableData))
                        {
                            XDocument document;
                            string tableDataFilename = Path.Combine(Path.GetDirectoryName(options.Configuration),
                                component.TableData);
                            try
                            {

                                using (StreamReader reader = new StreamReader(tableDataFilename))
                                {
                                    document = XDocument.Load(reader);
                                }
                            }
                            catch (Exception ex)
                            {
                                document = null;
                                WriteVerbose($"Unable to load table data document {tableDataFilename}. Error: {ex.Message}");
                            }
                            if (document != null)
                            {
                                UploadTableData(table, document);
                            }
                        }
                    }


                    foreach (ApplicationComponentSetting setting in component.Settings)
                    {
                        string resourceType = setting.ResourceType;
                        if (resourceType != null)
                        {
                            resourceType = resourceType.ToLower();
                            if (resourceType == "table")
                            {
                                CloudTableClient tableClient = storageAccount.CreateCloudTableClient();
                                CloudTable table = tableClient.GetTableReference(setting.Value);
                                table.CreateIfNotExists();

                                WriteVerbose($"Creating table {setting.Value} in {storageAccount.TableEndpoint}");
                            }
                            else if (resourceType == "queue")
                            {
                                CloudQueueClient queueClient = storageAccount.CreateCloudQueueClient();
                                CloudQueue queue = queueClient.GetQueueReference(setting.Value);
                                queue.CreateIfNotExists();
                                WriteVerbose($"Creating queue {setting.Value} in {storageAccount.TableEndpoint}");
                            }
                            else if (resourceType == "blob-container")
                            {
                                CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
                                CloudBlobContainer blobContainer = blobClient.GetContainerReference(setting.Value);
                                blobContainer.CreateIfNotExists();
                                WriteVerbose($"Creating blob container {setting.Value} in {storageAccount.TableEndpoint}");
                            }
                        }
                    }
                }
            }
        }