Строго набранные вызовы в web.config без дублирования имен свойств? - PullRequest
2 голосов
/ 12 июня 2009

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

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


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

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

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

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

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

Ответы [ 7 ]

3 голосов
/ 12 июня 2009

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

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

2 голосов
/ 12 июня 2009

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

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

1 голос
/ 07 апреля 2018

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

public string DateFormatString =>
    ConfigurationManager.AppSettings[MethodBase.GetCurrentMethod().Name.Replace("get_", "")];
1 голос
/ 12 июня 2009

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

1 голос
/ 12 июня 2009

Я создаю обертку для всего, что не принадлежит мне напрямую. Это включает в себя кэш, сеанс, конфигурацию, внешние веб-сервисы и т. Д. Это позволяет мне скрыть грязные детали использования этого виджета. В случае конфигурации у меня есть класс конфигурации, который предоставляет различные свойства, которые я разместил в своем 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;
        }
    }
}

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

1 голос
/ 12 июня 2009

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

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 голос
/ 12 июня 2009

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...