如何将内存中的一个类对象实体持久化到XML文件中
最近都在研究BlogEngine.NET的代码, 在看到BlogSettings类时, 一个Singleton模式, 最特别的是它的Save()方法和Load()方法, 因为我第一次看见这种利用反射方式持久化一个对象, 所以就将它截取下来, 学习学习了, 呵呵
Save()方法与Load很类似, 并且简单得多, 使用了Singleton模式, 使得反射的性能消耗, 只会发生在第一次初始化时:
呵呵, 得确如Dflying Chen 推荐的(本周ASP.NET英文技术文章推荐[05/20 - 06/02] -Official BlogEngine.NET 1.0 Release (BlogEngine.NET 1.0发布))"堪称学习ASP.NET 2.0的完美教材"那样, BlogEngine.NET 的代码确实是一目了然, 让人一看就能明白.
这段日子都会继续学习整个BlogEngine.NET 架构, 和其中的一些特别实用的方法, 呵呵, 如获至宝的感觉....
Load()
/// <summary>
/// Initializes the singleton instance of the <see cref="BlogSettings"/> class.
/// </summary>
private void Load()
{
//------------------------------------------------------------
// Local members
//------------------------------------------------------------
string settingsFilePath = String.Empty;
XmlReaderSettings readerSettings;
XmlDocument settingsDocument;
Type settingsType;
//------------------------------------------------------------
// Attempt to load configured settings
//------------------------------------------------------------
try
{
//------------------------------------------------------------
// Get settings location and instance type
//------------------------------------------------------------
settingsFilePath = HttpContext.Current.Server.MapPath(ConfigurationManager.AppSettings["SettingsFile"]);
settingsType = this.GetType();
//------------------------------------------------------------
// Define XML reader settings
//------------------------------------------------------------
readerSettings = new XmlReaderSettings();
readerSettings.IgnoreComments = true;
readerSettings.IgnoreWhitespace = true;
//------------------------------------------------------------
// Load settings into XML document
//------------------------------------------------------------
settingsDocument = new XmlDocument();
using (FileStream stream = new FileStream(settingsFilePath, FileMode.Open, FileAccess.Read))
{
using (XmlReader reader = XmlReader.Create(stream, readerSettings))
{
settingsDocument.Load(reader);
}
}
//------------------------------------------------------------
// Enumerate through individual settings nodes
//------------------------------------------------------------
foreach (XmlNode settingsNode in settingsDocument.SelectSingleNode("settings").ChildNodes)
{
//------------------------------------------------------------
// Extract the setting's name/value pair
//------------------------------------------------------------
string name = settingsNode.Name;
string value = settingsNode.InnerText;
//------------------------------------------------------------
// Enumerate through public properties of this instance
//------------------------------------------------------------
foreach (PropertyInfo propertyInformation in settingsType.GetProperties())
{
//------------------------------------------------------------
// Determine if configured setting matches current setting based on name
//------------------------------------------------------------
if (propertyInformation.Name.Equals(name, StringComparison.OrdinalIgnoreCase))
{
//------------------------------------------------------------
// Attempt to apply configured setting
//------------------------------------------------------------
try
{
propertyInformation.SetValue(this, Convert.ChangeType(value, propertyInformation.PropertyType, CultureInfo.CurrentCulture), null);
}
catch
{
// TODO: Log exception to a common logging framework?
}
break;
}
}
}
}
catch
{
//------------------------------------------------------------
// Rethrow exception
//------------------------------------------------------------
throw;
}
}
/// <summary>
/// Initializes the singleton instance of the <see cref="BlogSettings"/> class.
/// </summary>
private void Load()
{
//------------------------------------------------------------
// Local members
//------------------------------------------------------------
string settingsFilePath = String.Empty;
XmlReaderSettings readerSettings;
XmlDocument settingsDocument;
Type settingsType;
//------------------------------------------------------------
// Attempt to load configured settings
//------------------------------------------------------------
try
{
//------------------------------------------------------------
// Get settings location and instance type
//------------------------------------------------------------
settingsFilePath = HttpContext.Current.Server.MapPath(ConfigurationManager.AppSettings["SettingsFile"]);
settingsType = this.GetType();
//------------------------------------------------------------
// Define XML reader settings
//------------------------------------------------------------
readerSettings = new XmlReaderSettings();
readerSettings.IgnoreComments = true;
readerSettings.IgnoreWhitespace = true;
//------------------------------------------------------------
// Load settings into XML document
//------------------------------------------------------------
settingsDocument = new XmlDocument();
using (FileStream stream = new FileStream(settingsFilePath, FileMode.Open, FileAccess.Read))
{
using (XmlReader reader = XmlReader.Create(stream, readerSettings))
{
settingsDocument.Load(reader);
}
}
//------------------------------------------------------------
// Enumerate through individual settings nodes
//------------------------------------------------------------
foreach (XmlNode settingsNode in settingsDocument.SelectSingleNode("settings").ChildNodes)
{
//------------------------------------------------------------
// Extract the setting's name/value pair
//------------------------------------------------------------
string name = settingsNode.Name;
string value = settingsNode.InnerText;
//------------------------------------------------------------
// Enumerate through public properties of this instance
//------------------------------------------------------------
foreach (PropertyInfo propertyInformation in settingsType.GetProperties())
{
//------------------------------------------------------------
// Determine if configured setting matches current setting based on name
//------------------------------------------------------------
if (propertyInformation.Name.Equals(name, StringComparison.OrdinalIgnoreCase))
{
//------------------------------------------------------------
// Attempt to apply configured setting
//------------------------------------------------------------
try
{
propertyInformation.SetValue(this, Convert.ChangeType(value, propertyInformation.PropertyType, CultureInfo.CurrentCulture), null);
}
catch
{
// TODO: Log exception to a common logging framework?
}
break;
}
}
}
}
catch
{
//------------------------------------------------------------
// Rethrow exception
//------------------------------------------------------------
throw;
}
}
Save()方法与Load很类似, 并且简单得多, 使用了Singleton模式, 使得反射的性能消耗, 只会发生在第一次初始化时:
Instance
/// <summary>
/// Gets the singleton instance of the <see cref="BlogSettings"/> class.
/// </summary>
/// <value>A singleton instance of the <see cref="BlogSettings"/> class.</value>
/// <remarks></remarks>
public static BlogSettings Instance
{
get
{
if (blogSettingsSingleton == null)
{
blogSettingsSingleton = new BlogSettings();
}
return blogSettingsSingleton;
}
}
/// <summary>
/// Gets the singleton instance of the <see cref="BlogSettings"/> class.
/// </summary>
/// <value>A singleton instance of the <see cref="BlogSettings"/> class.</value>
/// <remarks></remarks>
public static BlogSettings Instance
{
get
{
if (blogSettingsSingleton == null)
{
blogSettingsSingleton = new BlogSettings();
}
return blogSettingsSingleton;
}
}
Save()
/// <summary>
/// Saves the settings to disk.
/// </summary>
public void Save()
{
//------------------------------------------------------------
// Local members
//------------------------------------------------------------
string settingsFilePath = String.Empty;
XmlWriterSettings writerSettings;
Type settingsType;
//------------------------------------------------------------
// Attempt to persist settings
//------------------------------------------------------------
try
{
//------------------------------------------------------------
// Get settings storage path and instance type
//------------------------------------------------------------
settingsFilePath = HttpContext.Current.Server.MapPath(ConfigurationManager.AppSettings["SettingsFile"]);
settingsType = this.GetType();
//------------------------------------------------------------
// Define XML writer settings used to generate output
//------------------------------------------------------------
writerSettings = new XmlWriterSettings();
writerSettings.Indent = true;
//------------------------------------------------------------
// Create XML writer against file path
//------------------------------------------------------------
using (XmlWriter writer = XmlWriter.Create(settingsFilePath, writerSettings))
{
//------------------------------------------------------------
// Write settings root element
//------------------------------------------------------------
writer.WriteStartElement("settings");
//------------------------------------------------------------
// Enumerate through settings properties
//------------------------------------------------------------
foreach (PropertyInfo propertyInformation in settingsType.GetProperties())
{
//------------------------------------------------------------
// Attempt to write settings name/value pairs
//------------------------------------------------------------
try
{
//------------------------------------------------------------
// Verify not
//------------------------------------------------------------
if (propertyInformation.Name != "Instance")
{
//------------------------------------------------------------
// Extract property value and its string representation
//------------------------------------------------------------
object propertyValue = propertyInformation.GetValue(this, null);
string valueAsString = propertyValue.ToString();
//------------------------------------------------------------
// Format null/default property values as empty strings
//------------------------------------------------------------
if (propertyValue.Equals(null))
{
valueAsString = String.Empty;
}
if (propertyValue.Equals(Int32.MinValue))
{
valueAsString = String.Empty;
}
if (propertyValue.Equals(Single.MinValue))
{
valueAsString = String.Empty;
}
//------------------------------------------------------------
// Write property name/value pair
//------------------------------------------------------------
writer.WriteElementString(propertyInformation.Name, valueAsString);
}
}
catch
{
// TODO: Log exception to a common logging framework?
}
}
//------------------------------------------------------------
// Write document end element
//------------------------------------------------------------
writer.WriteEndElement();
}
//------------------------------------------------------------
// Raise Changed event handler
//------------------------------------------------------------
OnChanged();
}
catch
{
//------------------------------------------------------------
// Rethrow exception
//------------------------------------------------------------
throw;
}
}
/// <summary>
/// Saves the settings to disk.
/// </summary>
public void Save()
{
//------------------------------------------------------------
// Local members
//------------------------------------------------------------
string settingsFilePath = String.Empty;
XmlWriterSettings writerSettings;
Type settingsType;
//------------------------------------------------------------
// Attempt to persist settings
//------------------------------------------------------------
try
{
//------------------------------------------------------------
// Get settings storage path and instance type
//------------------------------------------------------------
settingsFilePath = HttpContext.Current.Server.MapPath(ConfigurationManager.AppSettings["SettingsFile"]);
settingsType = this.GetType();
//------------------------------------------------------------
// Define XML writer settings used to generate output
//------------------------------------------------------------
writerSettings = new XmlWriterSettings();
writerSettings.Indent = true;
//------------------------------------------------------------
// Create XML writer against file path
//------------------------------------------------------------
using (XmlWriter writer = XmlWriter.Create(settingsFilePath, writerSettings))
{
//------------------------------------------------------------
// Write settings root element
//------------------------------------------------------------
writer.WriteStartElement("settings");
//------------------------------------------------------------
// Enumerate through settings properties
//------------------------------------------------------------
foreach (PropertyInfo propertyInformation in settingsType.GetProperties())
{
//------------------------------------------------------------
// Attempt to write settings name/value pairs
//------------------------------------------------------------
try
{
//------------------------------------------------------------
// Verify not
//------------------------------------------------------------
if (propertyInformation.Name != "Instance")
{
//------------------------------------------------------------
// Extract property value and its string representation
//------------------------------------------------------------
object propertyValue = propertyInformation.GetValue(this, null);
string valueAsString = propertyValue.ToString();
//------------------------------------------------------------
// Format null/default property values as empty strings
//------------------------------------------------------------
if (propertyValue.Equals(null))
{
valueAsString = String.Empty;
}
if (propertyValue.Equals(Int32.MinValue))
{
valueAsString = String.Empty;
}
if (propertyValue.Equals(Single.MinValue))
{
valueAsString = String.Empty;
}
//------------------------------------------------------------
// Write property name/value pair
//------------------------------------------------------------
writer.WriteElementString(propertyInformation.Name, valueAsString);
}
}
catch
{
// TODO: Log exception to a common logging framework?
}
}
//------------------------------------------------------------
// Write document end element
//------------------------------------------------------------
writer.WriteEndElement();
}
//------------------------------------------------------------
// Raise Changed event handler
//------------------------------------------------------------
OnChanged();
}
catch
{
//------------------------------------------------------------
// Rethrow exception
//------------------------------------------------------------
throw;
}
}
呵呵, 得确如Dflying Chen 推荐的(本周ASP.NET英文技术文章推荐[05/20 - 06/02] -Official BlogEngine.NET 1.0 Release (BlogEngine.NET 1.0发布))"堪称学习ASP.NET 2.0的完美教材"那样, BlogEngine.NET 的代码确实是一目了然, 让人一看就能明白.
这段日子都会继续学习整个BlogEngine.NET 架构, 和其中的一些特别实用的方法, 呵呵, 如获至宝的感觉....