zoukankan      html  css  js  c++  java
  • Enterprise Library Step By Step系列(二):配置应用程序块——进阶篇

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

    一.响应配置变更通知:

    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文件里面是不安全,我们可以用加密应用程序块对其进行加密,其实对于所有的应用程序块的配置信息都可以进行加密,我们到加密应用程序块时再详细讨论:)

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

    支持TerryLee的创业产品Worktile
    Worktile,新一代简单好用、体验极致的团队协同、项目管理工具,让你和你的团队随时随地一起工作。完全免费,现在就去了解一下吧。
    https://worktile.com
  • 相关阅读:
    2019-07-08 L410 EST科技英语翻译
    L405 NYC-ATF4
    L403 Royal espionage
    L402 EST
    L401 哭声识别
    L400 How Trees Affect the Weather
    L398
    final, finally, finalize 的区别
    try {}里有一个 return 语句, 那么紧跟在这个 try 后的 finally {}里的 code会不会被执行,什么时候被执行,在 return 前还是后?
    下 面 这 条 语 句 一 共 创 建 了 多 少 个 对 象 : String s="a"+"b"+"c"+"d";
  • 原文地址:https://www.cnblogs.com/Terrylee/p/255299.html
Copyright © 2011-2022 走看看