2009-09-18 2 views
6

Можно ли использовать неизменяемые типы в качестве свойств конфигурации с помощью API конфигурации .NET?Неизменяемые типы как свойства конфигурации

Скажем, у меня есть неизменный тип, который называется MyClass:

public class ImmutableClass 
{ 
    private readonly int value; 

    public ImmutableClass(int value) 
    { 
     this.value = value; 
    } 

    public int Value 
    { 
     get { return this.value; } 
    } 
} 

Я хотел бы использовать этот тип в качестве свойства конфигурации в ConfigurationSection:

public class MyConfigurationSection : ConfigurationSection 
{ 
    [ConfigurationProperty("foo")] 
    public ImmutableClass Foo 
    { 
     get { return (ImmutableClass)base["foo"]; } 
     set { base["foo"] = value; } 
    } 
} 

Когда я делаю это, я могу Сериализуем и десериализуем MyConfigurationSection, потому что это исключает это исключение:

System.Configurati on.ConfigurationErrorsException: значение критерия свойства не может быть преобразовано в строку. Ошибка: Невозможно найти конвертер, который поддерживает преобразование в/из строки для критерия свойства типа «FindCriterion».

Если я получить ImmutableClass от ConfigurationElement, я получаю это исключение при попытке сериализации и десериализации раздел конфигурации:

System.Reflection.TargetInvocationException: Исключение было брошено в целью вызова , ---> System.Reflection.TargetInvocationException: Исключение было выбрано целью вызова. ---> System.MissingMethodException: для объекта нет конструктора без параметров.

У меня есть полный контроль над ImmutableClass, поэтому я могу реализовать любой интерфейс.

Есть ли способ подключиться к API конфигурации, чтобы можно было использовать ImmutableClass таким образом?

ответ

1

Возможно, вы сможете использовать некоторые TypeConverters, чтобы помочь процессу (ссылка на System.Configurations.ConfigurationConverter).

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

+0

+1. Спасибо, это сработало просто отлично. Я согласен, что в большинстве случаев просто идти с потоком было бы проще, и это тоже то, что я обычно делаю, но это был особый случай ... –

+0

Полезно знать ... Я на самом деле экспериментирую с неизменяемыми типами и xaml сериализации. Я надеюсь, что преобразователи типов будут работать и на меня! – Will

4

Лично я думаю, что вам лучше отделить данные в конфигурации раздел (который, по-видимому, должен быть изменчивым) и как вы представляете его в своей объектной модели. Нет ничего, что остановило бы вас иметь два представления - простую (DTO/POCO) версию для конфигурации и вашу пользовательскую версию (неизменяемую в этом случае) для реального использования в вашем приложении.

+0

Я бы согласился в большинстве случаев, и это то, что я обычно делаю, но это был особый случай. –

0

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

Простейшим решением является установка другого уровня абстракции между конфигурацией и вашим приложением. Вы можете применить шаблон поставщика конфигурации и преобразовать измененные классы конфигурации «free for all» в неизменяемые классы, которые затем будут использоваться вашим приложением.

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

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

Обработчик конфигурации

public class SectionHandler : ConfigurationSection 
{ 
    [ConfigurationProperty("foo")] 
    public MyObject ConfigurationValue 
    { 
    get { return (MyObject) this["foo"]; } 
    } 
} 

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

Поставщик конфигурации будет может выглядеть примерно так:

public MyConfigurationProvider : IMyconfigurationProvider 
{ 

    public MyImmutabble ConfigurationValue 
    { 
    get 
    { 
     var configurationvalue = (MyObject) ConfigurationManager.GetSection("mySection"); 
     return new MyImmutable(configurationvalue.ConfigurationValue); 
    } 
    } 
} 

Это, как я это делаю, и он служил мне до сих пор.

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

+0

В нормальных случаях я полностью согласен с вами, и это тоже мой обычный подход, но это был особый случай. Я только что начал работать с TypeConverts, как предложил Уилл, и это сработало просто отлично, поэтому ваше первоначальное утверждение неверно. –

Смежные вопросы