2015-04-22 137 views
0

鑑於Azure Cloud Service,是否可以使用settings.setting文件而不是將它們存儲在<appSettings>Azure Cloud Service - settings.setting

我有這樣一個項目:

  • MyApp.Core - DLL
    • WorkerRole.cs
    • 的app.config
  • MyApp.Core.AzureService
    • ServiceConfiguration.Prod.cscfg
    • ServiceConfiguration.Staging.cscfg

app.config包含appSettings<add key="clientId" value="Dev"/>

隨後兩個cscfg文件可以忽略此設置是特定的蔚藍環境。例如,Prod.cscfg

<ConfigurationSettings> 
    <Setting name="clientId" value="Prod" /> 
</ConfigurationSettings> 

然後在Azure中我還可以自定義這些設置:

enter image description here

我可以切換到使用settings.setting文件,仍然允許蔚藍正確的電纜鋪設覆蓋?

回答

0

在玩了一段時間之後,我決定想出一個包裝類來處理這兩種情況。

它這樣使用:

public class Example 
{ 
    private readonly ICloudSettingsProvider _cloudSettingsProvider; 

    public void DoWork(){ 
     var setting = __cloudSettingsProvider.GetConfigurationSetting(
         () => Properties.Setting.Default.ExampleConfiguration); 

    } 
} 

實現:

public class CloudSettingsProvider : ICloudSettingsProvider 
{ 
    public T GetConfigurationSetting<T>(Expression<Func<T>> setting) 
    { 
     Guard.ArgumentNotNull(setting, "setting"); 

     var settingNames = new List<string>(); 
     T settingDefaultValue; 

     #region Parse settingNames/settingDefaultValue from setting Expression 
     try 
     { 
      var memberExpression = (MemberExpression) setting.Body; 

      //////Setting Name 
      var settingName = memberExpression.Member.Name; 

      if (string.IsNullOrEmpty(settingName)) 
       throw new Exception("Failed to get Setting Name (ie Property Name) from Expression"); 

      settingNames.Add(settingName); 

      //////Setting Full Name 
      var memberReflectedType = memberExpression.Member.ReflectedType; 

      if (null != memberReflectedType) 
       //we can use the settings full namespace as a search candidate as well 
       settingNames.Add(memberReflectedType.FullName + "." + settingName); 

      //////Setting Default Value 
      settingDefaultValue = setting.Compile().Invoke(); 
     } 
     catch (Exception e) 
     { 
      #region Wrap and Throw 
      throw new Exception("Failed to parse Setting expression. " + 
           "Expression should be like [() => Properties.Setting.Default.Foo]: " + e.Message, 
           e); 
      #endregion 
     } 
     #endregion 

     return GetConfigurationSettingInternal(
      settingDefaultValue, 
      settingNames.ToArray()); 
    }  

    private T GetConfigurationSettingInternal<T>(T defaultvalue = default(T), params string[] configurationSettingNames) 

    { 
     Guard.ArgumentNotNullOrEmptyEnumerable(configurationSettingNames, "configurationSettingNames"); 

     //function for converting a string setting found in the 
     //<appConfig> or azure config to type T 
     var conversionFunc = new Func<string, T>(setting => 
     { 
      if (typeof(T).IsEnum) 
       return (T)Enum.Parse(typeof(T), setting); 

      if (!typeof(T).IsClass || typeof(T) == typeof(string)) 
       //value type 
       return (T)Convert.ChangeType(setting, typeof(T)); 

      //dealing with a complex custom type, so let's assume it's 
      //been serialized into xml. 
      return 
       setting 
        .UnescapeXml() 
        .FromXml<T>(); 
     }); 


     /////////////// 
     // Note: RoleEnvironment isn't always available in Unit Tests 
     // Fixing this by putting a general try/catch and returning the defaultValue 
     ////////////// 
     try 
     { 
      if (!RoleEnvironment.IsAvailable) 
      { 
       //Check the <appSettings> element. 
       var appConfigValue = 
        configurationSettingNames 
         .Select(name => ConfigurationManager.AppSettings[name]) 
         .FirstOrDefault(value => !string.IsNullOrEmpty(value)); 

       return !string.IsNullOrEmpty(appConfigValue) 
        ? conversionFunc(appConfigValue) 
        : defaultvalue; 

      } 

      //Note: RoleEnvironment will fallback to <appConfig> 
      //http://stackoverflow.com/questions/11548301/azure-configuration-settings-and-microsoft-windowsazure-cloudconfigurationmanage 
      var azureConfigValue = 
       configurationSettingNames 
         .Select(name => RoleEnvironment.GetConfigurationSettingValue(name)) 
         .FirstOrDefault(value => !string.IsNullOrEmpty(value)); 

      return !string.IsNullOrEmpty(azureConfigValue) 
        ? conversionFunc(azureConfigValue) 
        : defaultvalue; 

     } 
     catch (InvalidCastException e) 
     { 
      _Logger.Warning(
       string.Format(
        "InvalidCastException getting configuration setting [{0}]." + 
        "This generally means the value entered is of the wrong type (ie " + 
        "it wants an Int, but the config value has non-numeric characters: {1}", 
         configurationSettingNames, e.Message), e); 
     } 
     catch (Exception e) 
     { 
      _Logger.Warning(
       string.Format(
        "Unhandled Exception getting configuration setting [{0}]: {1}", 
         configurationSettingNames, e.Message), e); 
     } 

     //If we are here, we hit an exception so return default value 
     return defaultvalue; 
    } 
相關問題