摘要:EnterpriseLibrary Configuration Facility就好像是在容器和数据类之间的桥,让我们可以轻松得去读取和操作配置文件。熟悉Enterprise Library的人都知道,在Enterprise Library中有一个Configuration Application Block,它可以使我们方便的从各种存储中读写配置信息,通过EnterpriseLibrary Configuration Facility我们就可以像使用普通的组件那样去注册一个数据类,它会用configurationkey来映射到Enterprise Library的配置文件中。
主要内容:
1.概述
2.使用Facility
3.原理浅析
一.概述
EnterpriseLibrary Configuration Facility就好像是在容器和数据类之间的桥,让我们可以轻松得去读取和操作配置文件。熟悉Enterprise Library的人都知道,在Enterprise Library中有一个Configuration Application Block,它可以使我们方便的从各种存储中读写配置信息,通过EnterpriseLibrary Configuration Facility我们就可以像使用普通的组件那样去注册一个数据类,它会用configurationkey来映射到Enterprise Library的配置文件中。先来看一下该Facility的相关信息:
Facility Information |
Uses Proxy | No |
Requires Configuration | Yes |
Uses Attributes | No |
Version | Beta 2 |
二.使用Facility
1.配置文件,这里使用配置文件注册组件的方式,放在应用程序配置文件中,这里唯一需要注意的是configurationkey,这个特性不能写错:
<?
xml version="1.0" encoding="utf-8"
?>
![None.gif](/Images/OutliningIndicators/None.gif)
<
configuration
>
![None.gif](/Images/OutliningIndicators/None.gif)
<
configSections
>
![None.gif](/Images/OutliningIndicators/None.gif)
<
section
name
="enterpriselibrary.configurationSettings"
type
="System.Configuration.IgnoreSectionHandler, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
/>
![None.gif](/Images/OutliningIndicators/None.gif)
<
section
name
="castle"
type
="Castle.Windsor.Configuration.AppDomain.CastleSectionHandler, Castle.Windsor"
/>
![None.gif](/Images/OutliningIndicators/None.gif)
</
configSections
>
![None.gif](/Images/OutliningIndicators/None.gif)
<
enterpriselibrary
.configurationSettings xmlns:xsd
="http://www.w3.org/2001/XMLSchema"
xmlns:xsi
="http://www.w3.org/2001/XMLSchema-instance"
![None.gif](/Images/OutliningIndicators/None.gif)
defaultSection
=""
applicationName
="Application"
xmlns
="http://www.microsoft.com/practices/enterpriselibrary/08-31-2004/configuration"
>
![None.gif](/Images/OutliningIndicators/None.gif)
<
configurationSections
>
![None.gif](/Images/OutliningIndicators/None.gif)
<
configurationSection
name
="EditorSettings"
encrypt
="false"
>
![None.gif](/Images/OutliningIndicators/None.gif)
<
storageProvider
xsi:type
="XmlFileStorageProviderData"
name
="XML File Storage Provider"
path
="../../EditorSettings.config"
/>
![None.gif](/Images/OutliningIndicators/None.gif)
<
dataTransformer
xsi:type
="XmlSerializerTransformerData"
name
="Xml Serializer Transformer"
>
![None.gif](/Images/OutliningIndicators/None.gif)
<
includeTypes
/>
![None.gif](/Images/OutliningIndicators/None.gif)
</
dataTransformer
>
![None.gif](/Images/OutliningIndicators/None.gif)
</
configurationSection
>
![None.gif](/Images/OutliningIndicators/None.gif)
</
configurationSections
>
![None.gif](/Images/OutliningIndicators/None.gif)
<
keyAlgorithmStorageProvider
xsi:nil
="true"
/>
![None.gif](/Images/OutliningIndicators/None.gif)
</
enterpriselibrary.configurationSettings
>
![None.gif](/Images/OutliningIndicators/None.gif)
<
castle
>
![None.gif](/Images/OutliningIndicators/None.gif)
<
facilities
>
![None.gif](/Images/OutliningIndicators/None.gif)
<
facility
id
="configuration"
type
="Castle.Facilities.EnterpriseLibrary.Configuration.EnterpriseConfigurationFacility, Castle.Facilities.EnterpriseLibrary.Configuration"
/>
![None.gif](/Images/OutliningIndicators/None.gif)
</
facilities
>
![None.gif](/Images/OutliningIndicators/None.gif)
<
components
>
![None.gif](/Images/OutliningIndicators/None.gif)
<
component
id
="editorfontdata"
type
="ConfigurationQuickStart.EditorFontData, Castle.Facilities.EnterpriseLibrary.Configuration.Tests"
![None.gif](/Images/OutliningIndicators/None.gif)
configurationkey
="EditorSettings"
/>
![None.gif](/Images/OutliningIndicators/None.gif)
<
component
id
="editorservice"
type
="Castle.Facilities.EnterpriseLibrary.Configuration.Tests.EditorService, Castle.Facilities.EnterpriseLibrary.Configuration.Tests"
/>
![None.gif](/Images/OutliningIndicators/None.gif)
</
components
>
![None.gif](/Images/OutliningIndicators/None.gif)
</
castle
>
![None.gif](/Images/OutliningIndicators/None.gif)
</
configuration
>
2.编写数据类文件:
public
class
EditorFontData
![ExpandedBlockStart.gif](/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
private string name;
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
private float size;
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
private int style;
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
public EditorFontData()
![ExpandedSubBlockStart.gif](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
}
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
public string Name
![ExpandedSubBlockStart.gif](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![ExpandedSubBlockStart.gif](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
get
{ return name; }
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
![ExpandedSubBlockStart.gif](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
set
{ name = value; }
}
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
public float Size
![ExpandedSubBlockStart.gif](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![ExpandedSubBlockStart.gif](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
get
{ return size; }
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
![ExpandedSubBlockStart.gif](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
set
{ size = value; }
}
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
public int Style
![ExpandedSubBlockStart.gif](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![ExpandedSubBlockStart.gif](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
get
{ return style; }
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
![ExpandedSubBlockStart.gif](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
set
{ style = value; }
}
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
public override string ToString()
![ExpandedSubBlockStart.gif](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
StringBuilder sb = new StringBuilder();
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
sb.AppendFormat("Name = {0}; Size = {1}; Style = {2}", name, size.ToString(), style.ToString());
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
return sb.ToString();
}
}
3.采用XML方式的存储
<?
xml version="1.0" encoding="utf-8"
?>
![None.gif](/Images/OutliningIndicators/None.gif)
<
EditorSettings
>
![None.gif](/Images/OutliningIndicators/None.gif)
<
xmlSerializerSection
type
="ConfigurationQuickStart.EditorFontData, Castle.Facilities.EnterpriseLibrary.Configuration.Tests, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"
>
![None.gif](/Images/OutliningIndicators/None.gif)
<
EditorFontData
xmlns:xsd
="http://www.w3.org/2001/XMLSchema"
xmlns:xsi
="http://www.w3.org/2001/XMLSchema-instance"
>
![None.gif](/Images/OutliningIndicators/None.gif)
<
Name
>
Microsoft Sans Serif
</
Name
>
![None.gif](/Images/OutliningIndicators/None.gif)
<
Size
>
9.25
</
Size
>
![None.gif](/Images/OutliningIndicators/None.gif)
<
Style
>
0
</
Style
>
![None.gif](/Images/OutliningIndicators/None.gif)
</
EditorFontData
>
![None.gif](/Images/OutliningIndicators/None.gif)
</
xmlSerializerSection
>
![None.gif](/Images/OutliningIndicators/None.gif)
</
EditorSettings
>
4.使用数据类的组件
public
class
EditorService
![ExpandedBlockStart.gif](/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
private readonly EditorFontData data;
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
public EditorService(EditorFontData data)
![ExpandedSubBlockStart.gif](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
this.data = data;
}
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
public EditorFontData Data
![ExpandedSubBlockStart.gif](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![ExpandedSubBlockStart.gif](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
get
{ return data; }
}
}
5.在容器中使用数据类
[TestFixture]
public
class
FacilityTestCase
![ExpandedBlockStart.gif](/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
[Test]
public void LoadingConfig()
![ExpandedSubBlockStart.gif](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
IWindsorContainer container = new WindsorContainer( new XmlInterpreter(new AppDomainConfigSource()) );
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
EditorService service = (EditorService) container[ typeof(EditorService) ];
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
Assert.AreEqual("Microsoft Sans Serif", service.Data.Name);
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
Assert.AreEqual(9.25,service.Data.Size);
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
}
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
}
可以看到,使用EnterpriseLibrary Configuration Facility非常的简单。最后还要注意一点,使用这个Facility需要安装Enterprise Library,因为它依赖于:
Microsoft.Practices.EnterpriseLibrary.Common.dll
![None.gif](/Images/OutliningIndicators/None.gif)
Microsoft.Practices.EnterpriseLibrary.Configuration.dll
三.原理分析
下面对这个Facility的原理做一下简单的分析。在初始化的时候,它注册了一个名为EntLibConfigurationInspector的分发器
public
class
EnterpriseConfigurationFacility : AbstractFacility
![ExpandedBlockStart.gif](/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
protected override void Init()
![ExpandedSubBlockStart.gif](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
Kernel.ComponentModelBuilder.AddContributor( new EntLibConfigurationInspector() );
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
}
}
![None.gif](/Images/OutliningIndicators/None.gif)
internal
class
EntLibConfigurationInspector : IContributeComponentModelConstruction
![ExpandedBlockStart.gif](/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
public void ProcessModel(IKernel kernel, ComponentModel model)
![ExpandedSubBlockStart.gif](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
if (model.Configuration == null) return;
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
String configKey = model.Configuration.Attributes["configurationkey"];
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
if (configKey == null) return;
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
model.ExtendedProperties["configurationkey"] = configKey;
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
model.CustomComponentActivator = typeof(EntLibComponentActivator);
}
}
在EntLibConfigurationInspector中为ComponentModel注册一个CustomComponentActivator类型的Activator,这个CustomComponentActivator的实现为EntLibComponentActivator。
internal
class
EntLibComponentActivator : AbstractComponentActivator
![ExpandedBlockStart.gif](/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
public EntLibComponentActivator(ComponentModel model, IKernel kernel,
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
ComponentInstanceDelegate onCreation, ComponentInstanceDelegate onDestruction) : base(model, kernel, onCreation, onDestruction)
![ExpandedSubBlockStart.gif](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
}
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
protected override object InternalCreate()
![ExpandedSubBlockStart.gif](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
String configKey = (String) Model.ExtendedProperties["configurationkey"];
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
return ConfigurationManager.GetConfiguration(configKey);
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
}
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
protected override void InternalDestroy(object instance)
![ExpandedSubBlockStart.gif](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
String configKey = (String) Model.ExtendedProperties["configurationkey"];
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
ConfigurationManager.WriteConfiguration(configKey, instance);
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
}
}
好了,关于EnterpriseLibrary Configuration Facility就简单的介绍到这里。
更多Castle文章可以访问:《Castle 开发系列文章》
参考资料
Castle的官方网站http://www.castleproject.org