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

    技术2022-05-11  70

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

    一.响应配置变更通知: 

    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; 910            EditorFontData configData = ConfigurationManager.GetConfiguration("EditorSettings"as EditorFontData;1112            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);2021            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接口:

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

     

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

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

     

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

    .创建自定义的Transformer

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

    2

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

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

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

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

     1 namespace  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; 910    using Microsoft.Practices.EnterpriseLibrary.Common;11    using Microsoft.Practices.EnterpriseLibrary.Configuration;1213    /// <summary>14    /// SoapSerializerTransformer is a custom Serialization Transformer for Microsft Enterprise Library 1.0.15    /// </summary>16    public class SoapSerializerTransformer : TransformerProvider17    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        }2324        public override object Serialize(object value)25        {26            SoapFormatter soapFormatter = new SoapFormatter();27            StringBuilder stringBuilder = new StringBuilder();28            XmlDocument doc = new XmlDocument();2930            stringBuilder.Append("<soapSerializerSection>");3132            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 padding38                serializedObject = ASCIIEncoding.ASCII.GetString(buffer).Replace('/0'' ').Trim();39            }40            stringBuilder.Append(serializedObject);4142            stringBuilder.Append("</soapSerializerSection>");43            doc.LoadXml(stringBuilder.ToString());4445            return doc.DocumentElement;46        }4748        public override object Deserialize(object section)49        {50            ArgumentValidation.CheckForNullReference(section, "section");51            ArgumentValidation.CheckExpectedType(section, typeof(XmlNode));5253            XmlNode sectionNode = (XmlNode)section;5455            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            }6061            SoapFormatter soapFormatter = new SoapFormatter();62            try63            {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)