Enterprise Library Step By Step系列(二):配置應用程序塊——進階篇
一.響應配置變更通知:
Configuration Application Block提供了一個事件機制,當存儲的配置變更時通知應用程序 ,使用步驟:
1)創(chuàng)建一個EverntHandler
/// <summary>2
/// 創(chuàng)建EventHanler3
/// </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)注冊事件
///注冊事件2
ConfigurationManager.ConfigurationChanged += new ConfigurationChangedEventHandler(OnConfigurationChanged); 二.配置數(shù)據(jù)的緩存:
Configuration Application Block在設計時提供了對配置數(shù)據(jù)的緩存,在讀取XML數(shù)據(jù)后,再次讀取它首先會判斷緩存是否為空,如果不為空,它會直接從緩存中讀取數(shù)據(jù)(在剖析篇中會有詳細的介紹)。
顯式的清除掉緩存用下面這句代碼即可:
///清除緩存數(shù)據(jù)2
ConfigurationManager.ClearSingletonSectionCache();三.面向高級人員的擴展機制:
1. 除了用XML文件可以存儲數(shù)據(jù)外,還可以創(chuàng)建自己的存儲方式,像SQL Server Database,注冊表存儲等,這時就需要我們自己創(chuàng)建StorageProvider。創(chuàng)建自定義的Storage Provider,需要注意以下幾點:
1)要讀取和寫入數(shù)據(jù),需要繼承于StorageProvider類和分別實現(xiàn)IStorageProviderReader和IstorageProviderWriter接口:
public class XmlFileStorageProvider : StorageProvider, IStorageProviderWriter2
{3
//……4
}2)如果實現(xiàn)了IConfigurationProvider接口,則方法Initialize()就不能為空,也必須實現(xiàn):
public override void Initialize(ConfigurationView configurationView)2
{3
//……4
}3)實現(xiàn)Read()和Write()方法,記住一定要返回類型為object,否則Transformer將無法使用:
public override object Read()2
{3
//……4
}5

6
public void Write(object value)7
{8
//……9
}2.創(chuàng)建自定義的Transformer
如果我們創(chuàng)建的自定義的Storage Provider不能后支持XMLNode,這時候我們需要創(chuàng)建自己的Transformer,需要注意以下幾點:
1)自定義的Transformer如果實現(xiàn)了Itransformer接口;則必須實現(xiàn)方法Serialize()和Deserialize();
2)自定義的Transformer如果實現(xiàn)了IConfigurationProvider接口,則方法Initialize()就不能為空,也必須實現(xiàn);
下面給出一個SoapSerializerTransformer的例子程序(先聲名一下,這個例子程序不是我寫的,而是Dario Fruk先生^_^):
namespace idroot.Framework.Configuration2
{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 : 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
}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 padding38
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
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:使用數(shù)據(jù)庫SQL Server Provider
Registry Provider:使用注冊表Provider
四.保護配置信息:
配置信息直接放在了XML文件里面是不安全,我們可以用加密應用程序塊對其進行加密,其實對于所有的應用程序塊的配置信息都可以進行加密,我們到加密應用程序塊時再詳細討論:)
進階篇就寫到這里了,后面繼續(xù)剖析篇,在剖析篇里我會從配置應用程序塊的底層設計,到類設計等作一些介紹(個人理解^_^)
Worktile,新一代簡單好用、體驗極致的團隊協(xié)同、項目管理工具,讓你和你的團隊隨時隨地一起工作。完全免費,現(xiàn)在就去了解一下吧。
https://worktile.com



浙公網(wǎng)安備 33010602011771號