В настоящее время мы используем гигантский объект конфигурации, который сериализируется к/от XML. Это хорошо работало по большей части, но мы находим, что в случае потерь мощности и сбоев приложения, что файл можно было оставить в состоянии, которое представляет его не могущий десериализовать правильно, эффективно повреждая конфигурационную информацию.
Я хотел бы использовать встроенный app.config, но это, кажется, легко не поддерживает пользовательские классы. Например, с сериализацией XML, я могу легко сериализировать дженерик list<ComplexClass>
без дополнительного кода. Это просто работает. Кажется, что при использовании app.config, необходимо обеспечить тонну информации и пользовательских классов для этого для работы. Плюс, большинство учебных руководств "по пользовательской конфигурации" от приблизительно 2007 и может устареть кто знает. У кого-либо есть информация к последнему способу сделать это в.NET 4.0?
Кроме того, когда проблема происходит в приложении, 9/10 времена это из-за неподходящей конфигурации. App.config нравится хранить изменяемые пользователем настройки в очень недоступном месте для пользователей, которые не знакомы со скрытыми каталогами и таким. Там какой-либо путь состоит в том, чтобы иметь единственное расположение для хранения файла конфигурации, который пользователь может легко послать нам по электронной почте, когда проблема происходит?
Или, действительно ли все это легче, чем я помню это находиться за ранние 2,0 дня? Любые ссылки или быстрые примеры того, как легко сделать пользовательскую app.config информацию, были бы большими.
Как дальнейший пример, это - вниз сокращенная версия одного из типов объектов, которые я хочу сериализировать как List<Alarm>
, как сумма Alarm
s может варьироваться или быть пустым. Существует ли аналогичный способ сохранить что-то вроде этого в app.config?
[Serializable]
public class Alarm
{
[Serializable]
public class AlarmSetting
{
public enum AlarmVariables { Concentration, RSquared }
public enum AlarmComparisons { LessThan, GreaterThan }
[Description("Which entity is being alarmed on.")]
public AlarmVariables Variable { get; set; }
[Description("Method of comparing the entity to the setpoint.")]
public AlarmComparisons Comparator { get; set; }
[Description("Value at which to alarm.")]
public Double Setpoint { get; set; }
}
public String Name { get; set; }
public Boolean Enabled { get; set; }
public String Parameter { get; set; }
public List<AlarmSetting> AlarmSettings { get; set; }
public System.Drawing.Color RowColor { get; set; }
}
Я бы предложил отказаться от любого вида конфигурационного файла и вместо этого использовать какой-нибудь тип локальной базы данных, например sqlite или sql server express, которые гораздо более устойчивы к сбоям приложения.
ИМХО, настройки конфигурации не должны быть контейнером по умолчанию для пользовательских настроек. На мой взгляд, конфигурационный файл нужен для того, чтобы убедиться, что приложение работает в заданном окружении. Например, определение строк подключения или скорости опроса или что-то в этом роде.
Пользовательские настройки, особенно те, которые часто меняются, нуждаются в лучшем механизме хранения, например, в локальной базе данных. Если, конечно, это не приложение клиент/сервер. В таком случае эти настройки должны храниться на самом сервере и сохраняться локально, только если приложение должно работать в отключенном состоянии.
Приведенный вами пример с настройкой того, что кажется одним или несколькими сигналами тревоги, является прекрасным примером того, что должно быть в таблице базы данных.
Я использую сериализацию XML, подобную той, которую вы описываете, в течение многих лет в ряде различных проектов. Если вы не хотите отказываться от SQL для настройки, это кажется лучшим решением.
IMHO, механизм app.config ничем не лучше прямой XML-сериализации. На самом деле, получить доступ к этой конфигурации из ряда различных проектов сложнее. Если вы сохраняете только переходное состояние (параметры пользователя и т. Д.) Из приложения WinForms, тогда настройки приложения могут быть удобны для простых типов данных.
Мне кажется, что у вас есть еще одна проблема, которая вызывает коррупцию. Я редко получаю повреждения файлов с этими XML-файлами. Всякий раз, когда я это делаю, это связано с исключением, которое возникает во время сериализации, а не из-за сбоя приложения и т. Д. Если вы хотите дважды проверить это, вы можете выполнить сериализацию в поток памяти, а затем сбросить поток памяти на диск. Фактически вы можете сериализовать, десериализовать поток, чтобы убедиться, что он действителен, прежде чем выгружать файл на диск.
Если вы не пишете этот файл много , я бы скептически отнесся к тому, что повреждение файла произошло из-за перебоев в подаче электроэнергии.
Если вы не сможете отследить источник ошибки, вы только догадываетесь, что она имеет какое-то отношение к файлам Xml. Вполне возможно, что встроенный XmlSerializer не работает .. например. у вас может быть где-то круговая ссылка, но ее трудно комментировать, если вы не знаете, в чем заключается ваша ошибка.
Иногда использование встроенного сериализатора Xml - не лучший выбор, и когда объекты становятся сложными, может быть лучше выполнить сериализацию и десериализацию самостоятельно. У вас будет больше контроля и вы сможете более точно определять / восстанавливать неверные данные файла.
XDocument doc = new XDocument(
new XElement("attachments",
new XElement("directory", attachmentDirectory),
new XElement("attachment-list",
from attached in attachedFiles
select new XElement("file",
new XAttribute("name", attached.FileName),
new XAttribute("size", attached.FileSize))
)
)
);
В остальном файлы конфигурации предназначены для конфигурации, а не для данных программы.Разница в том, что данные конфигурации не должны часто меняться и обычно не доступны для непосредственного редактирования пользователями. В приложении winforms вы не обмениваетесь данными между пользователями в файле конфигурации. Если да, то вам следует подумать, действительно ли ваше приложение является приложением базы данных.