CloudConfigurationManager does not pick up Applica

2019-01-25 04:51发布

问题:

I have a library containing some Azure helper classes. Inside these helper classes I obtain settings such as the Azure account name and key. When running in Azure these settings are picked up from the cloud configuration file (cscfg). This all works fine.

In order to unit test these classes outside of Azure (specifically the RoleEnvironment) I created settings of the same variable names within the unit test project. These actually get saved within an app.config file and are edited via the settings section which lives under the properties section of my test project. Rather than create my own method of abstracting the cloud configuration settings from web.config/app.config settings I decided to use the CloudConfigurationManager class. However, when I run my unit tests none of my settings are picked up so I simply get nulls. If however, I change my app.config file to use settings in the 'appSettings' format below, then I do get valid values. The downside of this is I can no longer edit my settings using the settings editor page within visual studio.

So my question is am I doing something wrong or is this a limitation of the cloud configuration manager, whereby it can only pick up manually added appSettings but not applicationSettings added using the editor?

<appSettings>
    <add key="Foo" value="MySettingValue"/>
</appSettings>

the above works, whereas the below does not:

<applicationSettings>
    <ComponentsTest.Properties.Settings>
      <setting name="Foo" serializeAs="String">
        <value>MySettingValue</value>
      </setting>
    </ComponentsTest.Properties.Settings>  
</applicationSettings>

回答1:

The CloudConfigurationManager only supports the AppSettings part of the web.config/app.config and will try to read values from here if the setting is missing from the Azure configuration. The documentation states that it won't read the web.config/app.config if the property RoleEnvironment.IsAvailable is true (running in Azure), but that is incorrect as we can see in the source code below (no check for IsAvailable).

You can take a look at the source to see what happens:

    /// <summary>
    /// Gets a setting with the given name.
    /// </summary>
    /// <param name="name">Setting name.</param>
    /// <returns>Setting value or null if such setting does not exist.</returns>
    internal string GetSetting(string name)
    {
        Debug.Assert(!string.IsNullOrEmpty(name));

        string value = null;

        value = GetValue("ServiceRuntime", name, GetServiceRuntimeSetting);
        if (value == null)
        {
            value = GetValue("ConfigurationManager", name, n => ConfigurationManager.AppSettings[n]);
        }

        return value;
    }

As you can see, there is only one call to the normal ConfigurationManager class that simply accesses the AppSettings.