我怎样才能使用动态settings.Blah而不是AppSettings [“blah”]?

时间:2011-02-05 01:18:00

标签: c# dynamic c#-4.0

我知道如何在C#4.0中使用dynamic,但是,我不确定如何采取措施并使其具有动态性(我的技术术语)。

例如,我如何制作一个包装,而不是ConfigurationManager.AppSettings["blah"],而是让我像动态一样使用它:settings.Blah

3 个答案:

答案 0 :(得分:9)

您仍然需要一个入口点。然而,从那里可能性非常灵活。这是一个示例想法,用于演示动态调度的强大功能:

public abstract class MyBaseClass
{
    public dynamic Settings
    {
        get { return _settings; }
    }

    private SettingsProxy _settings = new SettingsProxy();

    private class SettingsProxy : DynamicObject
    {
        public override bool TryGetMember(GetMemberBinder binder, out object result)
        {
            var setting = ConfigurationManager.AppSettings[binder.Name];
            if(setting != null)
            {
                result = setting.ToString();
                return true;
            }
            result = null;
            return false;
        }
    }
}

答案 1 :(得分:3)

带有泛型的新版本!!

public static  class WebConfiguration<T>
{
    public static dynamic Get {
        get { return _settings; }
    }

    static readonly SettingsProxy _settings = new SettingsProxy ();

    class SettingsProxy : DynamicObject
    {
        public override bool TryGetMember (GetMemberBinder binder, out object result)
        {
            var setting = ConfigurationManager.AppSettings [binder.Name];
            if (setting != null) {
                result = Convert.ChangeType (setting, typeof(T));
                return true;
            }
            result = null;
            return false;
        }
    }
}

用法

WebConfiguration<int>.Get.UserNameLength

答案 2 :(得分:1)

在这里,让我向您展示更多动态调度的力量:

/// <summary>
/// Dynamic wrapper for <see cref="AppSettingsSection"/>.
/// </summary>
public class DynamicAppSettings : DynamicObject
{
    private string _exeConfigPath;
    private System.Configuration.Configuration _config;

    /// <summary>
    /// Initializes a new instance of the <see cref="DynamicAppSettings"/> class with configuration file
    /// of the current application domain.
    /// </summary>
    public DynamicAppSettings()
        : this(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile)
    {
    }

    /// <summary>
    /// Initializes a new instance of the <see cref="DynamicAppSettings"/> class with the specified configuration file.
    /// </summary>
    /// <param name="exeConfigPath">Path to configuration file.</param>
    public DynamicAppSettings(string exeConfigPath)
    {
        if (string.IsNullOrEmpty(exeConfigPath))
            throw new ArgumentNullException("exeConfigPath");

        _exeConfigPath = exeConfigPath;
        _config = ConfigurationManager.OpenMappedExeConfiguration(
            new ExeConfigurationFileMap() { ExeConfigFilename = _exeConfigPath },
            ConfigurationUserLevel.None);
    }

    /// <summary>
    /// Gets the application settings entry from the configuration file.
    /// </summary>
    /// <param name="binder"></param>
    /// <param name="result"></param>
    /// <returns></returns>
    public override bool TryGetMember(GetMemberBinder binder, out object result)
    {
        result = _config.AppSettings.Settings[binder.Name];
        return true;
    }

    /// <summary>
    /// Adds or updates application settings entry.
    /// </summary>
    /// <param name="binder"></param>
    /// <param name="value"></param>
    /// <returns></returns>
    public override bool TrySetMember(SetMemberBinder binder, object value)
    {
        if (value != null && !(value is string))
        {
            return base.TrySetMember(binder, value);
        }

        if (_config.AppSettings.Settings[binder.Name] != null)
        {
            _config.AppSettings.Settings[binder.Name].Value = value.ToString();
        }
        else
        {
            _config.AppSettings.Settings.Add(binder.Name, value.ToString());
        }

        return true;
    }

    /// <summary>
    /// Invokes <see cref="Configuration.Save"/> method to save changes or removes an entry.
    /// </summary>
    /// <param name="binder"></param>
    /// <param name="args"></param>
    /// <param name="result"></param>
    /// <returns></returns>
    public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
    {
        if (binder.Name.Equals("Save", StringComparison.OrdinalIgnoreCase))
        {
            _config.Save();
            result = null;
            return true;
        }

        if (binder.Name.Equals("Remove", StringComparison.OrdinalIgnoreCase) &&
            args != null && args.Length == 1 && (args[0] is string))
        {
            _config.AppSettings.Settings.Remove(args[0].ToString());
            result = null;
            return true;
        }

        return base.TryInvokeMember(binder, args, out result);
    }
}

/// <summary>
/// Dynamic wrapper for <see cref="ConnectionStringsSection"/>.
/// </summary>
public class DynamicConnectionStrings : DynamicObject
{
    private string _exeConfigPath;
    private System.Configuration.Configuration _config;

    /// <summary>
    /// Initializes a new instance of the <see cref="DynamicConnectionStrings"/> class with the configuration file
    /// of the current application domain.
    /// </summary>
    public DynamicConnectionStrings()
        : this(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile)
    {
    }

    /// <summary>
    /// Initializes a new instance of the <see cref="DynamicConnectionStrings"/> class with the specified
    /// configuration file.
    /// </summary>
    /// <param name="exeConfigPath">Path to the configuration file.</param>
    public DynamicConnectionStrings(string exeConfigPath)
    {
        if (string.IsNullOrEmpty(exeConfigPath))
            throw new ArgumentNullException("exeConfigPath");

        _exeConfigPath = exeConfigPath;
        _config = ConfigurationManager.OpenMappedExeConfiguration(
            new ExeConfigurationFileMap() { ExeConfigFilename = _exeConfigPath },
            ConfigurationUserLevel.None);
    }

    /// <summary>
    /// Gets the connection string value from the configuration file.
    /// </summary>
    /// <param name="binder"></param>
    /// <param name="result"></param>
    /// <returns></returns>
    public override bool TryGetMember(GetMemberBinder binder, out object result)
    {
        result = _config.ConnectionStrings.ConnectionStrings[binder.Name].ConnectionString;
        return true;
    }

    /// <summary>
    /// Adds or updates a connection string entry in the configuration file.
    /// </summary>
    /// <param name="binder"></param>
    /// <param name="value"></param>
    /// <returns></returns>
    public override bool TrySetMember(SetMemberBinder binder, object value)
    {
        if (value != null && !(value is string))
        {
            return base.TrySetMember(binder, value);
        }

        if (_config.ConnectionStrings.ConnectionStrings[binder.Name] != null)
        {
            _config.ConnectionStrings.ConnectionStrings[binder.Name].ConnectionString = value.ToString();
        }
        else
        {
            _config.ConnectionStrings.ConnectionStrings.Add(
                new ConnectionStringSettings(binder.Name, value.ToString()));
        }

        return true;
    }

    /// <summary>
    /// Invokes <see cref="Configuration.Save"/> to save changes or removes an entry.
    /// </summary>
    /// <param name="binder"></param>
    /// <param name="args"></param>
    /// <param name="result"></param>
    /// <returns></returns>
    public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
    {
        if (binder.Name.Equals("Save", StringComparison.OrdinalIgnoreCase))
        {
            _config.Save();
            result = null;
            return true;
        }

        if (binder.Name.Equals("Remove", StringComparison.OrdinalIgnoreCase) &&
            args != null && args.Length == 1 && (args[0] is string))
        {
            _config.ConnectionStrings.ConnectionStrings.Remove(args[0].ToString());
            result = null;
            return true;
        }

        return base.TryInvokeMember(binder, args, out result);
    }
}

例如:

dynamic apps = new DynamicAppSettings();
apps.UploadLocation = "~/Uploads/";
apps.WebServiceUrl = "http://www.site.com/service.svc";
apps.Remove("TempFolderPath");
apps.Save();

dynamic conns = new DynamicConnectionStrings();
conns.MasterDatabase = "Data Source=lpc:(local);Integrated Security=True;Initial Catalog=master";
conns.Save();