ASP.NET应用程序的设置设计

时间:2018-04-09 16:22:22

标签: c# asp.net

首先,我一直在网上寻找设计设计模式,但我找不到适用于我的案例的解决方案,或者只能找到像 Use Dependency Injection 这样的神秘答案

问题

我有一个大型ASP .NET解决方案,可以部署到多个生产环境中。代码中的许多决策都是基于Web.config文件中实现的设置(几百个)。目前,他们都是使用NameValueCollection ConfigurationManager.AppSettings访问的。我想在数据库中移动这些设置,以便我可以创建用户界面并在之后更容易地修改它们。

我还希望从Web.config中继续访问这些设置,这样如果数据库出现问题,应用程序就不会中断。

解决方案架构

基本上,解决方案包括以下项目:

  • UI (这是Web.config文件所在的位置)
  • BLL
  • DAL
  • 集成项目1(应用程序与其他应用程序交互。此项目使用配置设置,如网址,身份验证信息等,目前作为方法中的参数传递 - 我个人觉得非常难看)
  • Integration Project 2
  • ...

守则

Setting类(数据库表几乎相同)。 SettingType是一个枚举,它定义了为UI定义的设置类型:Int,String,Bool和I.

public class Setting
{
    /// <summary>
    /// Gets or sets the identifier.
    /// </summary>
    /// <value>
    /// The identifier.
    /// </value>
    public int Id { get; set; }

    /// <summary>
    /// Gets or sets the name of the setting.
    /// </summary>
    /// <value>
    /// The name of the setting.
    /// </value>
    public string Name { get; set; }

    /// <summary>
    /// Gets or sets the type of the setting.
    /// </summary>
    /// <value>
    /// The type of the setting.
    /// </value>
    public SettingType Type { get; set; }

    /// <summary>
    /// Gets or sets the setting value.
    /// </summary>
    /// <value>
    /// The setting value.
    /// </value>
    public object Value { get; set; }

    /// <summary>
    /// Gets or sets the setting description.
    /// </summary>
    /// <value>
    /// The setting description.
    /// </value>
    public string Description { get; set; }

    /// <summary>
    /// Gets or sets the setting key.
    /// </summary>
    /// <value>
    /// The setting key.
    /// </value>
    public string Key { get; set; }

    /// <summary>
    /// Gets or sets the default value
    /// </summary>
    /// <value>
    /// The default value
    /// </value>
    public string Default { get; set; }
}

SettingHelper类(目前完成所有操作,将来会拆分功能):

public static class SettingHelper
{
    // Settings collection
    private static List<Setting> _settings;


    /// <summary>
    /// Reloads the settings.
    /// </summary>
    /// <exception cref="System.Exception"></exception>
    public static void LoadSettings()
    {
        _settings = new List<Setting>();
        // Code which loads the settings from the database
    }

    private static Setting GetSetting(string key)
    {
        try
        {
            // if settings are not loaded, we reload them from the database
            if (_settings == null || _settings.Count == 0)
                LoadSettings();

            var value = from Setting setting in _settings
                        where setting != null && setting.Key == key
                        select setting;

            return value.FirstOrDefault();
        }
        catch (Exception)
        {
            return null;
        }
    }

    public static void SetSetting(string key, object newValue, int userID)
    {
        var currentSetting = GetSetting(key);

        if (currentSetting != null && !Convert.ToString(currentSetting.Value).ToUpper().Equals(Convert.ToString(newValue).ToUpper()))
        {
            // Code which updates the setting value
        }
    }

    // For the UI
    public static IEnumerable<Setting> GetAllSettings()
    {
        if (_settings == null)
            LoadSettings();
        return _settings;
    }

    // To change back swiftly to the Web.config in case there are errors in production - will remove in the future
    public static bool SettingsFromDataBase
    {
        get
        {
            if (HttpContext.Current.Application["SettingsFromDataBase"] == null)
                HttpContext.Current.Application["SettingsFromDataBase"] = ConfigurationManager.AppSettings["SettingsFromDataBase"];

            bool settingsFromDataBase;
            if (bool.TryParse(HttpContext.Current.Application["SettingsFromDataBase"] as string, out settingsFromDataBase))
                return settingsFromDataBase;
            else return false;
        }
    }

    public static T ObjectToGenericType<T>(object obj)
    {
        if (obj is T)
        {
            return (T)obj;
        }
        else
        {
            try
            {
                return (T)Convert.ChangeType(obj, typeof(T));
            }
            catch (InvalidCastException)
            {
                return default(T);
            }
        }
    }

    public static T GetSetting<T>(string key)
    {
        if (SettingsFromDataBase)
        {
            var setting = GetSetting(key);
            return setting != null
                ? ObjectToGenericType<T>(setting.Value)
                : ObjectToGenericType<T>(ConfigurationManager.AppSettings[key]);
        }

        if (HttpContext.Current.Application[key] == null)
            HttpContext.Current.Application[key] = ConfigurationManager.AppSettings[key];

        return (T)HttpContext.Current.Application[key];

    }

    // The actual settings which will be used in the other projects
    public static string StringSetting
    {
        get { return GetSetting<string>("StringSetting"); }
    }

    public static bool BoolSetting
    {
        get { return GetSetting<bool>("BoolSetting"); }
    }

注意:可能使用Reflection对此类进行了改进,但我更愿意避免使用它(除了转换之外)。

问题

目前,SettingHelper位于UI项目中(为了能够从Web.config访问设置)。如何在BLL或集成项目中传输这些设置?

另外,你认为这个实现与静态列表中存储的所有设置是可行的吗?这感觉不太理想。

感谢任何有关改进的帮助或讨论。谢谢。

0 个答案:

没有答案