认真学习,虚心向高手们请教
配置应用程序块(不当之处请各位指出)⑴概述 假设我们的一个应用程序可能会使用同类型的几个的数据库(如使用两个SQL Server),也可能使用几个不同类型的数据库(如同时使用SQL Server和Sybase),还可能现在使用一种(个)数据库,将来很有可能要换成另一种(个),我们一般的解决办法是利用factory pattern,操作数据库的类根据外部的一个配置文件来创建,也就是说我们会在代码中读取外部配置数据,然后利用System.Activator的CreateInstance方法或System.Reflection.ConstructorInfo方法创建具体的操作数据库的类。配置应用程序块就是用了这种想法,具体功能的Provider(如操作数据库、写日志、执行权限管理等)在运行时根据外部配置数据生成,这里外部配置数据不仅仅是Xml格式的,还可以是注册表、数据库等格式,配置应用程序块读取某种格式的外部配置数据,转换成一个应用程序可操作的类(就是前面所说的8个Settings类)。由于外部配置数据格式可能不同,配置应用程序块要首先创建一个能够读取外部配置数据格式的对象,将外部配置数据读取过来,如果有必要,还需将读取过来的某格式的配置数据,转换成我们需要的类,这就要用到转换器。创建何种读写外部配置数据对象和类型转换器,也是要根据配置数据的,这样的配置数据放到了主配置文件App.config或Web.config中。如下所示:<configurationSection name="issueConfiguration" encrypt="true"> <storageProvider xsi:type="XmlFileStorageProviderData" name="XML File Storage Provider" path=".\config\issueConfiguration.config" /> <dataTransformer xsi:type="XmlSerializerTransformerData" name="Xml Serializer Transformer"> <includeTypes /> </dataTransformer> </configurationSection>看看storageProvider元素的含义,它有三个Attribute,xsi:type、name、path,我们知道在XSD定义中xsi:type="XmlFileStorageProviderData"是指明元素类型的,这里指外部配置数据是Xml格式的,name指明配置的名称,path指明外部配置数据的位置,在XmlFileStorageProviderData 类中有说明读取Xml格式外部配置数据的代码:typeof(XmlFileStorageProvider).AssemblyQualifiedName;从而说明读取Xml格式外部配置数据的类是XmlFileStorageProvider。⑵ConfigurationSettings类代表了配置元数据在配置应用程序块中ConfigurationSettings类代表了对外部配置数据的描述,注意它不是代表外部配置数据,代表的是外部配置数据的元数据,比较形象的展现如下图:
(图一:)ConfigurationSettings类进行XML串行化后,得到的内容显然ConfigurationSettings所代表的内容位于元配置文件(App.config/Web.config)中。配置应用程序块用ConfigurationSettings的提供的信息,读取外部配置数据,生成相应的Provider,对外提供数据操作、日志记录、权限管理等功能。实际上配置应用程序块并不是直接使用ConfigurationSettings,而是用了ConfigurationSettings的一个Wrapper:RuntimeConfigurationView,这应该是Facade Pattern(不知对不对?),同理,其他应用程序块的配置信息也有对应的Wrapper,如下:Security.SecurityConfigurationViewCaching.CachingConfigurationViewConfiguration.RuntimeConfigurationViewData.DatabaseConfigurationViewExceptionHandling.ExceptionHandlingConfigurationViewLogging.LoggingConfigurationViewSecurity.Cryptography.CryptographyConfigurationView他们都对应了相应的Settings类,这样Factory类就不用直接操作Settings类了,而是操作其Facade,即各个XXXXConfigurationView。⑶ConfigurationSettings对象的建立过程当我们要使用某项功能(数据操作、日志记录、权限管理等功能)时,配置应用程序块首先建立起ConfigurationSettings对象,从而使RuntimeConfigurationView可以实例化,配置工厂类根据RuntimeConfigurationView创建StorageProvider和TransformerProvider,从而在两者的配合下,读取外部配置文件,生成各个配置数据的Settings类,使XXXXConfigurationView可以实例化,工厂类根据XXXXConfigurationView创建相应的功能Provider,这样我们就可以开始消费各种功能了(注意,当我们使用自定义的配置数据时,读取我们自己命名外部配置文件,生成配置数据的Settings类就,算完成配置数据的读取了) 。
下面我们先看配置应用程序块是如何建立ConfigurationSettings对象的。1、 当我们用ConfigurationManager读写配置数据(非配置元数据)时, 会首先得到一个ConfigurationManager.Current对象, 这将导致调用ConfigurationManager的构造函数。2、 在ConfigurationManager的构造函数中, 会首先创建一个ConfigurationContext对象。3、而 创建ConfigurationContext对象, 则首先要求要有一个ConfigurationBuilder对象, 这样,当初始化一个ConfigurationManager对象时,主要的工作在与建立一个ConfigurationBuilder对象。4、 建立一个ConfigurationBuilder对象的步骤是:-----------得到元配置文件(App.config/Web.config)的文件名。 ----------根据元配置文件(App.config/Web.config)的文件名, 建立一个ConfigurationFile对象, 用于建立ConfigurationSettings对象。 ----------建立ConfigurationSettings对象,这是上面两步的最终目的,l也是ConfigurationBuilder对象创建时的主要任务,还有一些建立缓存、建立通知等任务。ConfigurationSettings对象具体创建过程是ConfigurationBuilder对象调用ConfigurationFile的如下方法 configFile.GetConfig(ConfigurationSettings.SectionName) as ConfigurationSettings,读取元配置文件中的enterpriselibrary.configurationSettings元素,得到一个XmlElement对象,然后对此XmlElement对象进行Deserialize便得到了ConfigurationSettings对象,XmlSerializer的Deserialize方法是在临时目录生成代码,然后将代码编译成一个Assembly,加载此Assembly,创建一个ConfigurationSettings对象,并给其各个字段、属性赋值,要注意建立后也给各个属性赋值了。那么是如何读取元配置文件中的enterpriselibrary.configurationSettings元素,得到一个XmlElement对象的呢?这里是使用了Xpath查询,其经典用法是:XmlDocument doc = new XmlDocument();//XPathDocument doc = new XPathDocument(fileName);XPathNavigator navigator = doc.CreateNavigator();XPathExpression expr = navigator.Compile("XXXXXXXXXXXXXXXXXX");XmlNamespaceManager nsmngr = new XmlNamespaceManager(navigator.NameTable);xnm.AddNamespace("XXXXXXXXXX", "urn:XXXXXXXXXXX");
expr.SetContext(nsmgr);XPathNodeIterator iterator = navigator.Select(expr);while (iterator.MoveNext()){ //XmlNode node = ((IHasXmlNode) iterator.Current).GetNode(); //如果是用XPathDocument建立导航器,则要用下面这句,先复制一个导航器,不要用原来的 //XPathNavigator nav2 = iterator.Current.Clone(); //具体功能代码写在此处;}
public object ReadConfiguration(string sectionName);public void WriteConfiguration(string sectionName, object configValue);
public ConfigurationSettings ReadMetaConfiguration();public ConfigurationSectionData ReadMetaConfiguration(string sectionName);public void WriteMetaConfig(ConfigurationSectionData configurationSectionData);public void WriteMetaConfiguration(ConfigurationSettings configurationSettings);
⑸配置应用程序块的使用步骤配置应用程序块主要是用来读取应用程序配置数据的,包括我们自定义的外部配置数据,在具体应用时并不是手动去写配置数据(比如一个Xml格式的配置文件),而是建立一个自定义配置数据类,配置应用程序块自己根据这个配置类创建、读写配置数据(如果配置数据为Xml格式,这个Xml格式的配置文件的创建、读写对我们来说是透明的,我们不要去修改这个文件。再说了,如果这个文件加密了,想改都难)。我们只要维护这个配置数据类就行了。这里需要注意的就是建立这个配置类时必须要由一个默认的构造方法,这是因为XmlSerializer在串行化和反串行化一个对象时都会根据默认的构造函数先创建此对象(因为说不准会用哪个构造函数,就用了默认的构造函数,这个应该是最好的选择了)。下面先简要介绍一下使用步骤。l第一步:建立一个自定义配置数据类。第二步:用配置控制台设置配置数据。第三步:用代码访问配置数据。这里假设我们已经建立了项目,并且已经有了Web.config后者App.congfig,如果你是在做WinForm应用程序,而且还没有App.congfig就先建一个。
1、建立自定义配置类自定义配置数据类的具体内容根据项目的要求决定,在项目开发中自定义配置数据类可能会不断修改。举个简单例子:Public class MySettings{ // 默认的构造函数(当然处理默认的构造函数,你完全可以重载更多的构造函数,但默认的不能少) Public MySettings() {} // Fields Private string orderName; Private int id; // properties Public string OrderName { Get{ return this. orderName ; } Set{ this. orderName = value; } } Public int Id { Get{ return this. id; } Set{ this. id= value; } }}自定义配置数据类其内部也可以有自定义的类,只要是XmlSerializer能够串行化的类就行,这样我们就可以设置一些复杂的配置数据,一般来说XmlSerializer能够串行化大部分类,但有些是不能串行化的,如DataReader,这样的类串行化也没有现实意义。再举个例子:Public class MySettings{ // 默认的构造函数(当然处理默认的构造函数,你完全可以重载更多的构造函数,但默认的不能少) Public MySettings() {} // Fields Private string orderName; Private OrderItem orderItem; // properties Public string OrderName { Get{ return this. orderName ; } Set{ this. orderName = value; } } Public OrderItem OrderDetailItem { Get{ return this. orderItem; } Set{ this. orderItem = value; } }}当然,这里我们也要定义一个OrderItem类,定义方法跟MySettings类差不多,就不赘述了。上面这两个仅仅是非常简单的自定义配置数据类,我们可以写非常复杂的自定义配置数据类。可以综合应用实体类、集合类写出非常复杂的配置类(具体可参看其他应用程序块的配置数据类XxxxSettings的写法)。基本上想要多复杂的就能写出多复杂的,因此完全可以满足我们应用程序的配置要求。当写完了配置类后就可以用配置控制台进行配置,从而可以操纵我们的配置类了。2、用配置控制台设置配置应用程序块①添加配置应用程序块。②添加一个Configuration Section,取一个有意义的名字,如Project Configuration。将来读写配置数据就靠这个Configuration Section的名字。③给这个Configuration Section添加一个XML File Storage Provider。设置其FileName属性,用于指定配置数据保存的外部配置文件,如project.config。④给这个Configuration Section添加一个Xml Serializer Transformer。设置完毕,保存所有设置。这样Web.config/App.config文件将会发生变化,并生成一个新的配置文件project.config。不过此时project.config是个空文件,里面什么都没有,而且,我们不需要添加、修改这个文件的任何内容,而是由程序去控制,你可以认为配置数据的保存是透明的。3、用代码访问配置数据写好配置类,设置好配置文件后,就可以读写配置数据了,不过在读之前要先写一次,要不然外部配置文件project.config是个空文件,你什么也读不出来。写一次后外部配置文件里就要扑内容了。写配置数据:ConfigurationManager.WriteConfiguration("issueConfiguration ", settings);注意WriteConfiguration 方法,有两个参数第一个就是我们前面提到的配置节名称,第二个就是自定义配置类的对象,这样,给我们的感觉就好像是将配置数据写到这个配置节里去了,这样理解完全是正确的,程序对此的处理是透明的。读配置数据:issueTracerSettings settings = ConfigurationManager.GetConfiguration("issueConfiguration") as IssueTracerSettings;GetConfiguration方法就是一个参数,即我们定义的配置节名称。注意别忘了进行强制类型转换。这样就完成了全部工作,不过现在应用程序都讲究安全,配置数据应该加密。4、加密配置数据Configuration Application Block----->Encrypting Settings点击右键,NewàFile Key Algorithm Storage Provider,将出现配置向导,只要根据向导设置就行了。在向导的最后将创建一个Key Algorithm Pair File,这个文件保存有Secure Key,这是加密和解密用的对称密钥,我们要妥善保管。如果你选择DPAPI保护,密钥将由系统保管,安全性更高,其缺点是只能在本机上使用。这就要求程序部署后,在本机上设置。
posted on 2005-08-03 23:35 生活、工作 阅读(3861) 评论(6) 编辑 收藏
Enterprise LibraryV1.1中,配置应用程序块在读取自己的配置数据和读取使用者配置数据的代码已经作了大量简化。 呵呵,同道中人,我还以为博客园中很少有人学习P&P呢,看到此文章,甚感欣慰,希望将来更多的人研究P&P,扩展P&P,最后能写我们自己的BLOCK! 回复 引用 查看
good 回复 引用 查看
快贴,快贴 一直想研究微软的企业库,记得去年的微软技术教育大会就在讲了。 谢谢共享! 回复 引用 查看
看了很多遍,反复看代码,有一点懂了。 回复 引用 查看
仿佛仍然是雾里看花. 回复 引用
等待我写的 制作自己的应用程序块 系列文章吧,将详细的分析一下代码,这篇文章写的却是很乱。 回复 引用 查看
Powered by: 博客园 Copyright © 生活、工作