Строго набранные вызовы в web.config без дублирования имен свойств?

2

Я искал здесь ответ. Прошу прощения, если это было задано раньше (как я подозреваю).

Сводка:. Как я могу строго набирать вызовы в свой web.config без дублирования имен свойств?


Детали: В моем коде я пытаюсь свести к минимуму использование строк, и мне не нравится определять что-то дважды.

Дополнением обоих этих выигрышей является мое ограничение использования AppSettings (и его строк) на один класс, который я ссылаюсь на весь проект. Класс AppSettings предоставляет публичные свойства:

    12   public static string DateFormatString {
    13       get {
    14           return ConfigurationManager.AppSettings["DateFormatString"];
    15       }
    16   }

Как я могу сохранить этот класс и предотвратить дублирование (строки 12 и 14) имени свойства?

В качестве альтернативы, какое другое решение вы могли бы порекомендовать?

Теги:
string
strong-typing
refactoring

7 ответов

3
Лучший ответ

Мне нравится использовать пользовательские обработчики конфигурации.

http://haacked.com/archive/2007/03/12/custom-configuration-sections-in-3-easy-steps.aspx

2

В вашем примере нет дублирования: One DateFormatString - это имя свойства, а другое - строка. Вы просто следуете за соглашением, которое однозначно идентифицирует свойство для ключа поиска для значения.

Я вижу одно возможное улучшение. Вы должны прочитать конфигурационный файл один раз в статическом конструкторе и сохранить значения, а не читать их из AppSettings каждый раз при доступе к ресурсу.

  • 0
    Отличное замечание о некогда / конструкторе. Что касается «без дублирования», я не хочу редактировать код в двух местах, когда я переименую одно из свойств в web.config.
  • 0
    Вы можете использовать настройки в файле ресурсов вместо web.config. Введите настройки на вкладке «Настройки» страниц свойств проекта.
1

Я написал пакет nuget, который делает это (между прочим). сопутствующий пост в блоге приводится в деталях, но этот упрощенный фрагмент показывает суть его как относящегося к вашему вопросу.

public string DateFormatString =>
    ConfigurationManager.AppSettings[MethodBase.GetCurrentMethod().Name.Replace("get_", "")];
1

Одно решение может быть

public enum Settings
{
    None,
    DateFormatString,
    DefeaultUserPrefix,
    SomeOtherValue
}

а затем иметь вспомогательный класс, например,

public static class ConfigurationHelper
{
     public static Get<T>(Settings setting)
     {
         string output = ConfigurationManager.AppSettings[setting.ToString()];
         if(string.isNullOrEmpty(output))
               throw new ConfigurationErrorsException("Setting " + setting + " is not defined in Configuration file.");
         return (T)output; //You can probably use Convert.* functions. 
     }
}

Ваш код вызова будет выглядеть следующим образом:

ConfigurationHelper.Get<string>(Settings.DateFormatString);

Приведенный выше подход обеспечивает некоторый уровень сильного ввода, но вам все равно нужно убедиться, что имя параметра в файле конфигурации совпадает с именем перечисления.

Лучшим выбором будет автоматический генерация класса на основе файла конфигурации.


Если вам нужны строго типизированные свойства, вы можете написать

public static string DateFormatString
{
    get { return ConfigurationHelper.Get<string>(Settings.DateFormatString); }
}

Кроме того, я бы советовал не читать конфигурационный файл в конструкторе (преждевременная оптимизация?). Если вы читаете конфигурационный файл в конструкторе, это означает, что вы не можете изменять файл конфигурации во время работы приложения.

1

Создайте свой собственный ConfigurationSection с помощью Configuration Section Designer, таким образом вам не нужно использовать AppSettings вообще... но у вас будет своя коллекция настроек, в которой даже будет Intellisense в файле web.config.

1

Я бы рекомендовал десериализацию web.config в объекте. Затем вы можете получить доступ ко всем записям конфигурации, как если бы они были свойствами (не может быть гораздо более строго типизировано, чем это!)

  • 0
    Как это согласуется с моей потребностью быть строго напечатанным? К какому типу объектов я бы обратился?
1

Я создаю оболочку для всего, что не принадлежит мне напрямую. Это включает в себя кеш, сеанс, конфигурацию, внешние веб-службы и т.д. Это позволяет мне инкапсулировать грязные детали использования этого виджета. В случае конфигурации у меня есть класс конфигурации bare bones, который предоставляет различные свойства, в которых я разместил свой app.config или web.config. Это может выглядеть примерно так:

using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Text;
using RanchBuddy.Core.Services.Impl;
using StructureMap;

namespace RanchBuddy.Core.Services.Impl
{
    [Pluggable("Default")]
    public class ConfigurationService : IConfigurationService
    {
        internal static int GetDefaultCacheDuration_Days()
        {
            return Convert.ToInt32(ConfigurationManager.AppSettings["DefaultCacheDuration_Days"]);
        }

        ...

        internal static LoggingType GetLoggingType()
        {
            string loggingType = ConfigurationManager.AppSettings["LoggingType"].ToString();
            if(loggingType.ToLower() == "verbose")
            {
                return LoggingType.Verbose;
            }
            else if (loggingType.ToLower() == "error")
            {
                return LoggingType.Error;
            }
            return LoggingType.Error;
        }

        ...

        public static string GetRoot()
        {
            string result = "";
            if(ConfigurationManager.AppSettings["Root"] != null)
            {
                result = ConfigurationManager.AppSettings["Root"].ToString();
            }
            return result;
        }
    }
}

Внутри вы можете сделать больше, чем просто получить значения из файла конфигурации. Вы можете преобразовать строку в тип, который должен быть. Вы можете использовать строку для определения возвращаемого значения перечисления. И т.д. Но ключ заключается в том, что любые изменения, которые когда-либо должны быть сделаны относительно конфигурации, могут быть сделаны здесь. Чтобы включить, если вы хотите поменять механизм хранилища конфигурации!

Ещё вопросы

Сообщество Overcoder
Наверх
Меню