c # НАСТРОЙКА архитектура - PullRequest
2 голосов
/ 08 июля 2010

У меня есть несколько приложений, которые должны читать и записывать настройки приложения. Так как одно из приложений является устаревшим приложением c ++ с сотнями настроек в реестре (и это не обязательно изменится), а также есть некоторые настройки, хранящиеся в проприетарном формате базы данных, мне интересно, как можно настроить архитектуру разрешить один интерфейс для чтения и / или записи настроек.
Одна идея состоит в том, чтобы существовать гигантское перечисление со всеми возможными настройками и разделение, которое направляет запрос на чтение / запись, основанный на гигантском регистре, правильному читателю или пишущему. В случае с реестром это должно было бы затем проанализировать возможности enum, чтобы найти местоположение ключа (если его настройка Http здесь, если это настройка Setup, расположенная в этом ключе). Вся эта идея заставляет меня думать, что не ООП и слишком много ручного тестирования. Помните, что существует около 30 настроек БД и, возможно, 70 настроек реестра.

public class SettingsTest
{
    public enum ESetting
    {
        HttpUserName, HttpPassword, SetupAllowPublic,  //db server stored
        HttpProxyUsername, HttpProxyPassword, PublicOrPrivate //registry stored
    }

    public string GetSetting(ESetting setting)
    {
        if (IsSettingInRegistry(setting)
            return RegHandler.GetFromRegistry(setting);
        else
            return DBHandler.GetFromDB(setting);
    }
}

1 Ответ

2 голосов
/ 08 июля 2010

Я думаю, что "большой" enum может быть немного неприятным - почему бы вам не разбить их, используя пространства имен;на цитата MSDN :

Обычно лучше определить перечисление непосредственно в пространстве имен, чтобы все классы в пространстве имен могли обращаться к нему с одинаковым удобством.Однако перечисление также может быть вложено в класс или структуру

Таким образом, вы можете иметь:

RediVider.EnterpriseApp.DataAccess.ESettingsKeys
RediVider.EnterpriseApp.BusinessLogic.ESettingsKeys
RediVider.EnterpriseApp.ComponentXXX.ESettingsKeys

Кроме того - вы бы объявляли перечисления или статические поля только для чтения?(где значение является ключом и работает в предположении, что когда вы определяете ключ, вы полностью определяете, откуда он исходит - отсюда и значение ключа).

Лучшей идеей было бы не определятьключ, специфичный для репозитория, но ключ, который сопоставлен с ключом AppSetting - и именно здесь вы определили фактический ключ, специфичный для репозитория.Это позволит вам изменить, где получить «настройку» из - через конфигурацию, без необходимости повторного развертывания приложения.

Итак, у вас есть:

namespace RediVider.EnterpriseApp.DataAccess
{
  Public class ESettingsKeys
  {
    // Note - AppSetting Keys are "namespaced" to match: 
    public readonly string SetupAllowPublic = "RediVider.EnterpriseApp.DataAccess.SetupAllowPublic";
  }
} 

Затем вваш конфиг ( псевдо-код ):

<AppSetting Key="RediVider.EnterpriseApp.DataAccess.SetupAllowPublic" value="/System/Settings/Blah/SetupAllowPublic">

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

  • Key
  • Value
  • Repository

Идея оператора switch не так уж и плоха, но вы можете использовать тот же подход и здесь, используя своего рода подход на основе шаблонов Facade или Factory:

  • Имеют различные конкретные методы,настройки из хранилища.
  • В каждом пространстве имен (согласно перечислениям ESetting) есть метод «GetSettings», который делает то, что вы описали, - но только для параметров, определенных в этом пространстве имен.
...