Как бы я создать составные настройки для приложения? - PullRequest
3 голосов
/ 27 августа 2011

Я хотел бы иметь универсальный класс настроек, который я могу использовать в составном приложении.Поскольку я добавляю функции и компоненты и составляю приложение, используя MEF & Prism, я хотел бы иметь окно настроек, которое автоматически загружает интерфейс настроек каждого из модулей в окно (используя Prism & MEF)

Естьмного разных способов работы с настройками, и один из них мне нравится:

public class AppData : ApplicationSettingsBase
{
  [UserScopedSetting()]
  [DefaultSettingValue("true")]
  public bool Clipboard
  {
    get { return ((bool)this["Clipboard"]); }
    set { this["Clipboard"] = (bool)value; }
  }
}

Это позволяет мне установить значение по умолчанию, и я предполагаю, что если приложение не находитЗатем файл .settings создаст файл со значениями по умолчанию.Однако мне нужно было бы написать несколько пользовательских кодов для каждого раздела настроек модулей и либо создать уникальное диалоговое окно для каждого модуля, либо попытаться создать диспетчер настроек, который загружал бы их все вручную.

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

Итак, было бы приемлемо создать интерфейс Isettings, который каким-то образом использовал ApplicationSettingsBase, чтобы я мог использовать MEF, чтобы найти все реализации Isettings ввсе модули в каталоге, а затем составляют диалог с вкладками для каждой найденной реализации?В интерфейсе Isettings у меня могут быть некоторые базовые свойства, такие как Name и все остальное, что потребуется для маркировки и описания модуля в окне MEF WPF.

Единственное, что мне не нравится, это наличие строки атрибуты повсюду.Есть ли способ бегло разобраться с настройками?Я имею в виду наличие реализации ISettings, что вы бы явно закодировали настройку примерно так:

public class AppData : ISettings
{ 
    Setting Clipboard = new Setting();
    Clipboard.Scope = SettingScope.User;
    Clipboard.SettingType = List<String>;

    List<String> DefaultClipboards = new List<String>();
    DefaultClipboards.Add("FoxClipboard");
    Clipboard.DefaultSetting = DefaultClipboards;
}

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

Это правильный путь для включения?Есть ли какая-то структура или проект, который я пропустил, который обрабатывает то, к чему я стремлюсь?Я думаю, что, вероятно, есть лучший способ, чем я обрисовал в общих чертах?

Я уверен, что этот вопрос возник при разработке составных приложений, но я не нашел основы или ответа, который очерчивает этот сценарий.

Мне удалось создать составное приложение со слабой связью и динамически подключать мои модули с помощью MEF & Prism, но я не смог найти удовлетворительного способа для работы с настройками комбинированным способом.

Ответы [ 2 ]

1 голос
/ 27 августа 2011

Отказ от ответственности : У меня нет опыта работы с пользовательскими реализациями ApplicationSettingsBase, поэтому я не могу помочь с его фактической реализацией и даже положительно сказать, что этот подход будет работать. Однако то, что я предлагаю , может быть путём, который стоит изучить, если вы действительно хотите использовать ApplicationSettingsBase.

Прежде всего, ISettings не может наследовать ApplicationSettingsBase, потому что интерфейсы могут наследовать только другие интерфейсы.

Мое предложение состоит в том, чтобы создать пользовательскую реализацию ApplicationSettingsBase, параметризованную экземпляром ISettings. Таким образом, всякий раз, когда вы получаете ISettings от ваших компонентов, вы создаете новый CustomAppSettings (см. Ниже) и связываете его с вашим компонентом.

Поскольку ApplicationSettingsBase использует сопоставление пары ключ-значение строки-объекта, я предлагаю интерфейс, который делает то же самое.

public interface ISettings
{
    Dictionary<string,object> Values{ get; set; }

    public object GetDefaultValue(string key);

    // Whatever else you might need
}

public class CustomAppSettings : ApplicationSettingsBase
{
    public ISettings Settings { get; set; }

    public override object this[string propertyName]
    {
        get
        {
            return this.Settings.Values[propertyName];
        }
        set
        {
            this.Settings.Values[propertyName] = value;
        }
    }

    // There will be more implementation work for this class I'm sure
}

Кроме того, вам потребуется механизм сериализации для ваших экземпляров ISetting.

Редактировать: Исправлены некоторые ошибки синтаксиса кода

1 голос
/ 27 августа 2011

Я решил что-то похожее для одного из моих приложений на работе. Мы склонялись дальше к вашей второй идее, где есть просто интерфейс базовых настроек «ISettings», который мы использовали для композиции MEF.

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

Для пользовательского интерфейса у нас были модули с пользовательскими настройками, которые также экспортировали «рабочее пространство настроек», которое мы загружали в пользовательский интерфейс настроек. Используя рефлексию, мы написали метод, который будет делать глубокую копию объекта настроек, чтобы мы могли выполнить прямую привязку mvvm к клонированному объекту (для отмены функциональности), а также взять объект и скопировать его свойства обратно.

Отражением было разрешение общего клона / копии без написания кода для каждого объекта настроек.

Кроме того, одна вещь, которую мы по-прежнему любим и по сей день для привязки модели данных, - это интерфейс INotifyPropertyChanged. Наш базовый объект ISettings требует этого. Это позволяет не только пользовательскому интерфейсу настроек напрямую связываться с настройками и прослушивать изменения, но когда мы нажимаем «Применить» или «ОК», все наши модели данных, которым требуются настройки, регистрируются для события пропущенного изменения, поэтому все они автоматически получают уведомление, когда параметр имеет измененное.

Проверьте Property Observer , если вы планируете выполнить маршрут уведомления. Это приложение было развернуто, и я все еще чувствую, что наша инфраструктура настроек чрезвычайно успешна.

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

Надеюсь, это поможет!

...