技术开发 频道

Enterprise Library Step By Step系列(二):配置应用程序块——进

【IT168技术文档】 在前一篇文章中,讲述了配置应用程序块的最简单的介绍,在本篇文章中我主要介绍一下配置应用程序块的响应配置变更通知,保护配置信息(加密配置信息),面向高级人员的扩展机制,配置数据的缓存等几个方面。在剖析篇中我会去分析配置应用程序块的底层设计及类设计。

一.响应配置变更通知:

Configuration Application Block提供了一个事件机制,当存储的配置变更时通知应用程序 ,使用步骤:

1)创建一个EverntHandler

1/**//// <summary> 2 /// 创建EventHanler 3 /// </summary> 4 /// <param name="sender"></param> 5 /// <param name="args"></param> 6 private void OnConfigurationChanged
(
object sender, ConfigurationChangedEventArgs args) 7 { 8 Cursor = System.Windows.Forms.Cursors.WaitCursor; 9 10 EditorFontData configData = ConfigurationManager.GetConfiguration
(
"EditorSettings") as EditorFontData; 11 12 StringBuilder results = new StringBuilder(); 13 results.Append("Configuration changes in storage were detected. Updating
configuration.
"); 14 results.Append(Environment.NewLine); 15 results.Append("New configuration settings:"); 16 results.Append(Environment.NewLine); 17 results.Append('\t'); 18 results.Append(configData.ToString()); 19 results.Append(Environment.NewLine); 20 21 Cursor = System.Windows.Forms.Cursors.Arrow; 22 }

2)注册事件

1/**////注册事件 2 ConfigurationManager.ConfigurationChanged +=
new ConfigurationChangedEventHandler(OnConfigurationChanged);

二.配置数据的缓存:

Configuration Application Block在设计时提供了对配置数据的缓存,在读取XML数据后,再次读取它首先会判断缓存是否为空,如果不为空,它会直接从缓存中读取数据(在剖析篇中会有详细的介绍)。

显式的清除掉缓存用下面这句代码即可:

1/**////清除缓存数据 2 ConfigurationManager.ClearSingletonSectionCache();

三.面向高级人员的扩展机制:

1 除了用XML文件可以存储数据外,还可以创建自己的存储方式,像SQL Server Database,注册表存储等,这时就需要我们自己创建StorageProvider。创建自定义的Storage Provider,需要注意以下几点:

1)要读取和写入数据,需要继承于StorageProvider类和分别实现IStorageProviderReaderIstorageProviderWriter接口:

1public class XmlFileStorageProvider : StorageProvider, IStorageProviderWriter 2 { 3 //…… 4 }

2)如果实现了IConfigurationProvider接口,则方法Initialize()就不能为空,也必须实现:

1public override void Initialize(ConfigurationView configurationView) 2 { 3 //…… 4 }

3)实现Read()Write()方法,记住一定要返回类型为object,否则Transformer将无法使用:

1public override object Read() 2 { 3 //…… 4 } 5 6 public void Write(object value) 7 { 8 //…… 9 }

2.创建自定义的Transformer

如果我们创建的自定义的Storage Provider不能后支持XMLNode,这时候我们需要创建自己的Transformer,需要注意以下几点:

1)自定义的Transformer如果实现了Itransformer接口;则必须实现方法Serialize()Deserialize();

2)自定义的Transformer如果实现了IConfigurationProvider接口,则方法Initialize()就不能为空,也必须实现;

下面给出一个SoapSerializerTransformer的例子程序(先声名一下,这个例子程序不是我写的,而是Dario Fruk先生^_^):

1namespace idroot.Framework.Configuration 2{ 3 using System; 4 using System.Configuration; 5 using System.IO; 6 using System.Runtime.Serialization.Formatters.Soap; 7 using System.Text; 8 using System.Xml; 9 10 using Microsoft.Practices.EnterpriseLibrary.Common; 11 using Microsoft.Practices.EnterpriseLibrary.Configuration; 12 13 /**//// <summary> 14 /// SoapSerializerTransformer is a
//custom Serialization Transformer for Microsft Enterprise Library 1.0.
15 /// </summary> 16 public class SoapSerializerTransformer : TransformerProvider 17 { 18 public override void Initialize(ConfigurationView configurationView) 19 { 20 // Do nothing. This implementation does not require any additional
// configuration data because SoapFormatter reflects types
21 // during serialization. 22 } 23 24 public override object Serialize(object value) 25 { 26 SoapFormatter soapFormatter = new SoapFormatter(); 27 StringBuilder stringBuilder = new StringBuilder(); 28 XmlDocument doc = new XmlDocument(); 29 30 stringBuilder.Append("<soapSerializerSection>"); 31 32 string serializedObject = ""; 33 using (MemoryStream stream = new MemoryStream()) 34 { 35 soapFormatter.Serialize(stream, value); 36 byte[] buffer = stream.GetBuffer(); 37 // quick fix for 0-byte padding 38 serializedObject = ASCIIEncoding.ASCII.GetString(buffer).
Replace(
'\0', ' ').Trim(); 39 } 40 stringBuilder.Append(serializedObject); 41 42 stringBuilder.Append("</soapSerializerSection>"); 43 doc.LoadXml(stringBuilder.ToString()); 44 45 return doc.DocumentElement; 46 } 47 48 public override object Deserialize(object section) 49 { 50 ArgumentValidation.CheckForNullReference(section, "section"); 51 ArgumentValidation.CheckExpectedType(section, typeof(XmlNode)); 52 53 XmlNode sectionNode = (XmlNode)section; 54 55 XmlNode serializedObjectNode = sectionNode.SelectSingleNode
(
"//soapSerializerSection"); 56 if (serializedObjectNode == null) 57 { 58 throw new ConfigurationException
(
"The required element '<soapSerializationSection>'
missing in the specified Xml configuration file.
"); 59 } 60 61 SoapFormatter soapFormatter = new SoapFormatter(); 62 try 63 { 64 object obj = null; 65 using (MemoryStream stream = new MemoryStream()) 66 { 67 using (StreamWriter sw = new StreamWriter(stream, Encoding.ASCII)) 68 { 69 sw.Write(serializedObjectNode.InnerXml); 70 sw.Flush(); 71 // rewind stream to the begining or deserialization will
// throw Exception.
72 sw.BaseStream.Seek(0, SeekOrigin.Begin); 73 obj = soapFormatter.Deserialize(stream); 74 } 75 } 76 return obj; 77 } 78 catch (InvalidOperationException e) 79 { 80 string message = e.Message; 81 if (null != e.InnerException) 82 { 83 message = String.Concat(message, " ", e.InnerException.Message); 84 } 85 throw new ConfigurationException(message, e); 86 } 87 } 88 } 89}

3.使用其它的Providers

       SQL Server Provider:使用数据库SQL Server Provider

       Registry Provider:使用注册表Provider

四.保护配置信息:

配置信息直接放在了XML文件里面是不安全,我们可以用加密应用程序块对其进行加密,其实对于所有的应用程序块的配置信息都可以进行加密,我们到加密应用程序块时再详细讨论:)

进阶篇就写到这里了,后面继续剖析篇,在剖析篇里我会从配置应用程序块的底层设计,到类设计等作一些介绍(个人理解^_^

0
相关文章