Search code examples
azure-storageazure-blob-storageasp.net-core-2.1azure-storage-emulator

Running Azure Storage Emulator programmatically


I'm using an Azure Blob Storage for storing photos. It works fine. To connect to the storage I added an AzureStorageConfig in my appsettings.json:

"AzureStorageConfig": {
    "AccountName": "<accountname>",
    "ImageContainer": "<containername>",
    "AccountKey": "<accountkey>"
}

I additionally created a class AzureStorageConfig

 public class AzureStorageConfig
    {
        public string AccountKey { get; set; }
        public string AccountName { get; set; }
        public string BaseUrl { get; set; }
        public Uri BlobEndpoint { get; set; }
        public string ImageContainer { get; set; }
        public Uri QueueEndpoint { get; set; }
        public Uri TableEndpoint { get; set; }
    }

and configured it in the Startup.cs:

services.Configure<AzureStorageConfig>(Configuration.GetSection(nameof(AzureStorageConfig)));

So the config can be injected via dependency injection.

For the appsettings.development.json I'd like to use the Azure Storage Emulator. I found several tutorials but all of them use a connection string to connect to the emulator and not a config.

I tried with the data I found on the Microsoft pages:

     "AzureStorageConfig": {
    "AccountName": "devstoreaccount1",
    "ImageContainer": "images",
    "AccountKey": "Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==",
    "BlobEndpoint": "http://127.0.0.1:10000/devstoreaccount1",
    "TableEndpoint": "http://127.0.0.1:10002/devstoreaccount1",
    "QueueEndpoint": "http://127.0.0.1:10001/devstoreaccount1"
}

I Initialize the objects like this:

public class AzureStorageService
    {
        private readonly CloudBlobContainer _imageContainer;
        private readonly AzureStorageConfig _storageConfig; 

public AzureStorageService(IOptions<AzureStorageConfig> config)
            {  
                _storageConfig = config.Value;
                CloudStorageAccount storageAccount;
                StorageCredentials storageCredentials = new StorageCredentials(_storageConfig.AccountName, _storageConfig.AccountKey);

                if (_storageConfig.BlobEndpoint == null)
                {
                    storageAccount = new CloudStorageAccount(storageCredentials, true);
                }
                else
                {
                    storageAccount = new CloudStorageAccount(
                        storageCredentials,
                        _storageConfig.BlobEndpoint,
                        _storageConfig.QueueEndpoint,
                        _storageConfig.TableEndpoint,
                        null);
                }

                CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
                _imageContainer = blobClient.GetContainerReference(_storageConfig.ImageContainer);
                _imageContainer.CreateIfNotExistsAsync().Wait();
            }
}

I had to start the emulator manually by starting the "Microsoft Azure Compute Emulator" app. How can I start (and initialize) the emulator programmatically for the automated tests (and also for the Azure Devops CI that runs these tests)?

Thanks a lot.


Solution

  • You should change your code to be use Connection string which is the same as using the account name and key but it will be easier when you use the emulator by just changing the connection string to "UseDevelopmentStorage=true;".

    As for starting the emulator, You can check the hosting environment variable in startup.cs file for the environment:

       public void Configure(IApplicationBuilder app, IHostingEnvironment env, IServiceProvider serviceProvider, ILoggerFactory loggerFactory)
            {
                if (env.IsDevelopment())
                {
                    //Start the Emulator here by initiating a new process that calls the emulator.exe file
                }
    }
    

    The other solution would be using a hosted service and do the same check for environment and start the emulator in the StartAsync and stop it in the StopAsync

    See this link for more details Background tasks with hosted services in ASP.NET Core