揭开.NET 2.0配置之谜(二)

声明:此文是译文,原文是Jon RistaUnraveling the Mysteries of .NET 2.0 Configuration,由于这篇文章比较长,所以我就分为几部分来翻译,这是此译文的第二部分。

PS:首先说声sorry,发布的揭开.NET2.0配置之谜(一)排版错乱给大家阅读带来了不便,不过现在已经修正。原因是我用Windows live writer发布译文之后,用博客园中的TinyMCE编辑了一下,保存之后就出现了排版错乱问题。

let's go on!

5、添加自定义元素

默认情况下,自定义配置节中所有的配置属性(properties)在.config文件中被表示成属性(attributes)。这并不总是必然
的,然而,一个更复杂XML结构,由属性(attributes)和元素(elements)混合组成的,是需要的。不要怕:.NET的配置系统完全支持
自定义配置元素,他们的属性(properties)可以是属性(attributes)或者多个嵌套元素。要创建自定义配置元素,简单地写一个类继承自ConfigurationElement而不是ConfigurationSection。配置元素的执行细节跟配置节一样,不同之处是元素必须嵌套在配置节中。

让我们继续,嵌套一个自定义元素在ExampleSection中。让我们这个嵌套元素存储一个DateTime值和一个整数值。创建这个类的代码如下所示:

#region Using Statements
using System;
using System.Configuration;
#endregion

namespace Examples.Configuration
{
    /// <summary>
    /// An example configuration element class.
    /// </summary>
    public class NestedElement: ConfigurationElement
    {
        #region Constructors
        /// <summary>
        /// Predefines the valid properties and prepares
        /// the property collection.
        /// </summary>
        static NestedElement()
        {
            // Predefine properties here
            s_propDateTime = new ConfigurationProperty(
                "dateTimeValue",
                typeof(DateTime),
                null,
                ConfigurationPropertyOptions.IsRequired
            );

            s_propInteger = new ConfigurationProperty(
                "integerValue",
                typeof(int),
                0,
                ConfigurationPropertyOptions.IsRequired
            );

            s_properties = new ConfigurationPropertyCollection();

            s_properties.Add(s_propDateTime);
            s_properties.Add(s_propInteger);
        }
        #endregion

        #region Static Fields
        private static ConfigurationProperty s_propDateTime;
        private static ConfigurationProperty s_propInteger;

        private static ConfigurationPropertyCollection s_properties;
        #endregion

        #region Properties
        /// <summary>
        /// Gets the DateTimeValue setting.
        /// </summary>
        [ConfigurationProperty("dateTimeValue", IsRequired=true)]
        public DateTime StringValue
        {
            get { return (DateTime)base[s_propDateTime]; }
        }

        /// <summary>
        /// Gets the IntegerValue setting.
        /// </summary>
        [ConfigurationProperty("integerValue")]
        public int IntegerValue
        {
            get { return (int)base[s_propInteger]; }
        }

        /// <summary>
        /// Override the Properties collection and return our custom one.
        /// </summary>
        protected override ConfigurationPropertyCollection Properties
        {
            get { return s_properties; }
        }
        #endregion
    }
}

将这个元素加到我们之前创建的ExampleSection中,就像定义一个新属性一样简单。下面展示了添加一个嵌套元素的必要代码:

    public class ExampleSection: ConfigurationSection
    {
        #region Constructors
        /// <summary>
        /// Predefines the valid properties and prepares
        /// the property collection.
        /// </summary>
        static ExampleSection()
        {
            // Create other properties...

            s_propElement = new ConfigurationProperty(
                "nestedElement",
                typeof(NestedElement),
                null,
                ConfigurationPropertyOptions.IsRequired
            );

            s_properties = new ConfigurationPropertyCollection();

            // Add other properties...
            s_properties.Add(s_propElement);
        }
        #endregion

        #region Static Fields
        private static ConfigurationProperty s_propElement;
        // Other static fields...
        #endregion

        #region Properties
        // ...

        /// <summary>
        /// Gets the NestedElement element.
        /// </summary>
        [ConfigurationProperty("nestedElement")]
        public NestedElement Nested
        {
            get { return (NestedElement)base[s_propElement]; }
        }

        // ...
        #endregion
    }

最后,在我们的XML配置文件中使用这个元素只需要简单地在<example>标记中添加<nestedElement>标记。
值得注意的是,只能有一个nestedElement实例在example中。这种方式创建的嵌套元素,不允许有类似命名的元素集合。它允许一个特定元素
的单个实例,在自定义节的一个特定的嵌套深度。下一节将讲在一个配置节中定义元素集合。完整的App.config文件应该像下面这样:

<configuration>
  <configSections>
    <section name="example" type="Examples.Configuration.ExampleSection,
                                  Examples.Configuration" />
  </configSections>

  <example
    stringValue="A sample string value."
    boolValue="true"
    timeSpanValue="5:00:00"
  >
    <nestedElement
      dateTimeValue="10/16/2006"
      integerValue="1"
    />
  </example>
</configuration>

使用新的套元素又是非常的简单,因为Nested属性(property)将暴露给我们的前面例子中使用的节变量:

private string m_string;
private bool m_bool;
private TimeSpan m_timespan;
private DateTime m_datetime;
private int m_int;

void GetExampleSettings()
{
    ExampleSection section = ConfigurationManager.GetSection("example")
                             as ExampleSection;
    if (section != null)
    {
        m_string = section.StringValue;
        m_bool = section.BooleanValue;
        m_timespan = section.TimeSpanValue;
        m_datetime = section.Nested.DateTimeValue;
        m_int = section.Nested.IntegerValue;
    }
}

每个配置节可以由任意数量的属性(attributes)和元素(elements)组成,元素可以嵌套的任意的深度以满足应用程序。相对于其他
XML用法,这总是一个好主意,符合相同的XML自定义配置节的最佳做法。作为一般规则,数据集或大量的信息不应该保存在自定义配置节。我们将在高级配置
主题那节讨论原因。这些“配置”部分,应该用于存储结构化的应用配置信息。

6、添加元素集合

在上一节,我们在一个配置节元素中创建一个嵌套元素。嵌套的元素仅限于只有一个实例,且必须出现在指定的元素中。创建元素集合或元素列表需要不同的和稍微复杂的方法。在配置文件中要创建一个配置元素集合或列表,你必须要创建一个类继承自ConfigurationElementCollection。几种集合可以被创建,两个主要集合类型是BasicMap和AddRemoveClearMap。

任何用过<appSettings>配置节的人都会熟悉AddRemoveClearMap的集合类型。AddRemoveClearMap是ASP.NET

web.config文件中的一个级联集合。级联集合允许元素在web站点路径级添加,移除或清除在低级别的应用程序级。此外,在低级别添加的任何新的唯
一元素都将和高级别的所有元素合并。请参阅附录A,更多细节关于配置如何级联作用。Basic
map更为严格,但允许其他不是“add”名称的元素添加到一个集合中。一个Basic
map的别的元素名称的例子是System.Web的<customError>节,它支持一个<error>元素的集合。

由于AddRemoveClearMap集合是默认类型,让我们创建一个并将它加到我们之前的配置节例子中。创建一个元素集合的代码比配置节或单个元素要稍微复杂一些,但是整体来说仍然非常简单。下面的元素集合代码遵循一个标准模式,.NET 2.0框架中大部分元素集合都是它:

[ConfigurationCollection(typeof(ThingElement),
    CollectionType=ConfigurationElementCollectionType.AddRemoveClearMap)]
public class ExampleThingElementCollection: ConfigurationElementCollection
{
    #region Constructors
    static ExampleThingElementCollection()
    {
        m_properties = new ConfigurationPropertyCollection();
    }

    public ExampleThingElementCollection()
    {
    }
    #endregion

    #region Fields
    private static ConfigurationPropertyCollection m_properties;
    #endregion

    #region Properties
    protected override ConfigurationPropertyCollection Properties
    {
        get { return m_properties; }
    }

    public override ConfigurationElementCollectionType CollectionType
    {
        get { return ConfigurationElementCollectionType.AddRemoveClearMap; }
    }
    #endregion

    #region Indexers
    public ThingElement this[int index]
    {
        get { return (ThingElement)base.BaseGet(index); }
        set
        {
            if (base.BaseGet(index) != null)
            {
                base.BaseRemoveAt(index);
            }
            base.BaseAdd(index, value);
        }
    }

    public ThingElement this[string name]
    {
        get { return (ThingElement)base.BaseGet(name); }
    }
    #endregion

    #region Overrides
    protected override ConfigurationElement CreateNewElement()
    {
        return new ThingElement();
    }

    protected override object GetElementKey(ConfigurationElement element)
    {
        return (element as ThingElement).Name;
    }
    #endregion
}

一般都需要提供一个通过数字索引的索引器。通过一个元素的关键字索引的索引器也是非常方便的。在这个例子中,关键字是一个字符串名称。两个重写方法CreateNewElementGetElementKey,对于确保你的集合功能正常非常重要。CreateNewElement有两个重载的方法,一个没有参数,另一个以一个元素名作参数,如果你重载了默认的AddRemoveClearMap行为。更多的关于这个将在高级主题那节讨论。默认,CreateNewElement(string elementName)重载调用CreateNewElement(),所以他并非总是需要重载的。GetElementKey
回指定的配置元素的值,而且返回值唯一标识他。在我们的例子中,关键字是Name属性(property),将在我们的ThingElement定义。最
后,你可能已经注意到属性(Properties)集合被重写了。这个原因不是很明显,除非你深入研究.NET框架的源代码,但是可以说这是一个性能优
化。

我们的集合并没有完全完成,我们需要收集一些东西。对于我们的例子,就是ThingElement。这是另外一个ConfigurationElement类,类似于我们的之前的NestedElement。

public class ThingElement: ConfigurationElement
{
        #region Constructors
        /// <summary>
        /// Predefines the valid properties and prepares
        /// the property collection.
        /// </summary>
        static ThingElement()
        {
            // Predefine properties here
            s_propName = new ConfigurationProperty(
                "name",
                typeof(string),
                null,
                ConfigurationPropertyOptions.IsRequired
            );

            s_propType = new ConfigurationProperty(
                "type",
                typeof(string),
                "Normal",
                ConfigurationPropertyOptions.None
            );

            s_propColor = new ConfigurationProperty(
                "color",
                typeof(string),
                "Green",
                ConfigurationPropertyOptions.None
            );

            s_properties = new ConfigurationPropertyCollection();

            s_properties.Add(s_propName);
            s_properties.Add(s_propType);
            s_properties.Add(s_propColor);
        }
        #endregion

        #region Static Fields
        private static ConfigurationProperty s_propName;
        private static ConfigurationProperty s_propType;
        private static ConfigurationProperty s_propColor;

        private static ConfigurationPropertyCollection s_properties;
        #endregion

        #region Properties
        /// <summary>
        /// Gets the Name setting.
        /// </summary>
        [ConfigurationProperty("name", IsRequired=true)]
        public string Name
        {
            get { return (string)base[s_propName]; }
        }

        /// <summary>
        /// Gets the Type setting.
        /// </summary>
        [ConfigurationProperty("type")]
        public string Type
        {
            get { return (string)base[s_propType]; }
        }

        /// <summary>
        /// Gets the Type setting.
        /// </summary>
        [ConfigurationProperty("color")]
        public string Color
        {
            get { return (string)base[s_propColor]; }
        }

        /// <summary>
        /// Override the Properties collection and return our custom one.
        /// </summary>
        protected override ConfigurationPropertyCollection Properties
        {
            get { return s_properties; }
        }
        #endregion
}

我们的ThingElement很简单,只提供了一个名称、类型和颜色。现在你应该注意到,至此我们的配置类中我们已经重写了Properties集合。这不是一个不要的步骤,但它可以提高配置节的性能和效率。更多详细介绍在高级主题那节。我们可以通过添加另一个ConfigurationProperty使
这个集合在我们的ExampleSection中可以访问,实现方法和NestedElement一样。只是这次,用
ExampleThingElementCollection替换了NestedElement。用“Thing”命名元素,现在由我们的代码支持的例子
如下:

<configuration>
  <configSections>
    <section name="example" type="Examples.Configuration.ExampleSection,
                                     Examples.Configuration" />
  </configSections>

  <example
    stringValue="A sample string value."
    boolValue="true"
    timeSpanValue="5:00:00"
  >
    <nestedElement
      dateTimeValue="10/16/2006"
      integerValue="1"
    />
    <things>
      <add name="slimy" type="goo" />
      <add name="metal" type="metal" color="silver" />
      <add name="block" type="wood" color="tan" />
    </things>
  </example>
</configuration>

7、高级元素集合

在上一节中,您学习了如何创建一个标准的AddRemoveClearMap集合类型,它也是默认的类型。总共有四个类型的集合(有两种类型,每种类型有两种版本):AddRemoveClearMapAddRemoveClearMapAlternate以及BasicMapBasicMapAlternate。从上一节,我们知道AddRemoveClearMap是如何其作用的。BasicMap 限制比AddRemoveClearMap 强,它不允许较低级的web.config修改从较高级的web.config继承的任何东西,但它允许除<add>名称之外的元素。两种主要类型的替换版本只是对元素的排序不同,添加继承的元素,将它们他在最后。

译注:ConfigurationElementCollectionType 枚举,指定 ConfigurationElementCollectionType 对象的类型,包含以下4种类型:

BasicMap
此类型的集合包含应用于指定的级别(由这些元素指定)和所有子级别的元素。子级别不能修改由此类型的父元素指定的属性。

AddRemoveClearMap
ConfigurationElementCollection 的默认类型。此类型的集合包含可在配置文件的层次结构中进行合并的元素。在这类层次结构的任何特定级别中,均可使用 add、remove 和 clear 指令修改任何继承的属性和指定新的属性。

BasicMapAlternate
除了使 ConfigurationElementCollection 对象对其内容进行排序以将继承的元素排列在最后外,此类型与 BasicMap 相同。

AddRemoveClearMapAlternate
除了使 ConfigurationElementCollection 对象对其内容进行排序以将继承的元素排列在最后外,此类型与 AddRemoveClearMap 相同。

在前面的例子里,我们创建了一个集合表示things,而且每一个thing都是通过<add>元素来添加的。对于我们的目的,完全支
持级联联合可能是没有必要的,而且用<thing>作为元素的名字比<add>好。我们可以使用很多种方法来完成这个,但是我们
将使用最常见的修改我们原来的ThingElementCollection类为BasicMap 并使用元素名字<thing>:

[ConfigurationCollection(typeof(ThingElement), AddItemName="thing",
      CollectionType=ConfigurationElementCollectionType.BasicMap)]
public class ExampleThingElementCollection: ConfigurationElementCollection
{
    #region Constructors
    // ...
    #endregion

    #region Fields
    // ...
    #endregion

    #region Properties
    // ...

    public override ConfigurationElementCollectionType CollectionType
    {
        get { return ConfigurationElementCollectionType.BasicMap; }
    }

    protected override string ElementName
    {
        get { return "thing"; }
    }
    #endregion

    #region Indexers
    // ...
    #endregion

    #region Methods
    // ...
    #endregion

    #region Overrides
    // ...
    #endregion
}

这些简单的修改将更新我们的集合类为BasicMap ,这将使得在.config文件中可以使用元素<thing>添加新项,而不是<add>。现在我们可以这样修改我们的配置文件,比以前的版本更漂亮、更清楚:

<configuration>
  <configSections>
    <section name="example" type="Examples.Configuration.ExampleSection,
                                     Examples.Configuration" />
  </configSections>

  <example
    stringValue="A sample string value."
    boolValue="true"
    timeSpanValue="5:00:00"
  >
    <nestedElement
      dateTimeValue="10/16/2006"
      integerValue="1"
    />
    <things>
      <thing name="slimy" type="goo" />
      <thing name="metal" type="metal" color="silver" />
      <thing name="block" type="wood" color="tan" />
    </things>
  </example>
</configuration>

有时候,当我们有一个层次结构的配置,而且设置级联从一个父web.config到子web.config,我们需要控制那些元素显示在集合的前
面。默认,所有元素以继承的顺序。当有多个web.config文件合并时,这种顺序不是特别好定义。通过使用替换的集合类型(译注:即BasicMapAlternateAddRemoveClearMapAlternate),我们可以控制迫使所以继承的元素被列在最后。级联三个web.config文件将以读取文件的顺序列出所有项,以最低级的web.config开始,随后是他的父web.config们,最后是根web.config。BasicMapAlternateAddRemoveClearMapAlternate都是这种方式,而且警告添加时修改父级别的web.config的项。

8、自定义配置节组

根据你致力于的项目类型或者特定于你的应用程序的配置需求,你可能会觉得使用配置节组更有用。.NET 2.0提供了便利的配置功能来完成这事,之前我们讨论的ASP.NET的<system.web>配置组就是。创建一个配置节组比创建一个配置节更简单,但是使用和访问他们呢稍微复杂一些。假定我们有两个配置节类叫做ExampleSection 和AnotherSection,我们可以像这样写成一个配置组:

public sealed class ExampleSectionGroup: ConfigurationSectionGroup
{
    #region Constructors
    public ExampleSectionGroup()
    {
    }
    #endregion

    #region Properties
    [ConfigurationProperty("example")]
    public ExampleSection Example
    {
        get { return (ExampleSection)base.Sections["example"]; }
    }

    [ConfigurationProperty("another")]
    public AnotherSection Another
    {
        get { return (AnotherSection)base.Sections["another"]; }
    }
    #endregion
}

一旦我们有了节组代码,我们需要在.config文件中定义它。和定义一个一般的节类似,只是增加了层次级别。值得注意的是,ExampleSection 和AnotherSection现在必须作为我们配置组的子节点定义:

<configuration>
  <configSections>
    <sectionGroup name="example.group"
        type="Examples.Configuration.ExampleSectionGroup,
              Examples.Configuration">
      <section name="example" type="Examples.Configuration.ExampleSection,
                                       Examples.Configuration" />
      <section name="another" type="Examples.Configuration.AnotherSection,
                                       Examples.Configuration" />
    </sectionGroup>
  </configSections>

  <example.group>

    <example
      stringValue="A sample string value."
      boolValue="true"
      timeSpanValue="5:00:00"
    >
      <nestedElement
        dateTimeValue="10\16\2006"
        integerValue="1"
      />
      <things>
        <thing name="slimy" type="goo" />
        <thing name="metal" type="metal" color="silver" />
        <thing name="block" type="wood" color="tan" />
      </things>
    </example>

    <another value="someValue" />

  </example.group>

这个配置节组做了这些,使两个配置节在一个组。此外,它提供了一个访问这些节的中心点。一旦我们有一个引用指向我们的ConfigurationSectionGroup对象,我们可以访问ExampleSection 和AnotherSection,而不用再次调用ConfigurationManager.GetSection()。但是,获取最初的引用指向我们的ExampleSectionGroup并不和获取一个单独的节那样简单。专研.NET 2.0深入一点,我们将发现Configuration类。这个类直接表示一个应用程序定义在它的.config文件中的配置。跟ConfigurationManager类一样,Configuration有一个GetSection()方法,以及附加了GetSectionGroup()方法。我们可以访问配置节组和里面的配置节,例如:

虽然上面的代码不是很复杂,要求一个Configuration对象来获得GetSectionGroup()方法不是很明显。一旦我们有一个Configuration对象,然而,你会发现一些他的额外有用的功能。在下一节中,我们将讨论用Configuration对象来将修改保存回配置文件,只要支持保存。

9、保存配置更改

到目前为止,我们已经研究了使用.NET 2.0的配置功能来定义和加载配置设置。对于许多应用程序来说,这是不够的。和使用一样,有许多时候必须保存配置。在上一节中,我们使用了Configuration对象,它提供给开发者一种将修改编程式地保存回配置节。唯一的先决条件就是配置对象允许有变更。让我们回顾一下原来的ExampleSection类,并使它可修改:

      #region Properties
        /// <summary>
        /// Gets the StringValue setting.
        /// </summary>
        [ConfigurationProperty("stringValue", IsRequired=true)]
        public string StringValue
        {
            get { return (string)base[s_propString]; }
            set { base[s_propString] = value; }
            // Allows setting to be changed
        }

        /// <summary>
        /// Gets the BooleanValue setting.
        /// </summary>
        [ConfigurationProperty("boolValue")]
        public bool BooleanValue
        {
            get { return (bool)base[s_propBool]; }
            set { base[s_propBool] = value; }
            // Allows setting to be changed
        }

        /// <summary>
        /// Gets the TimeSpanValue setting.
        /// </summary>
        [ConfigurationProperty("timeSpanValue")]
        public TimeSpan TimeSpanValue
        {
            get { return (TimeSpan)base[s_propTimeSpan]; }
            set { base[s_propTimeSpan] = value; }
            // Allows setting to be changed
        }

        /// <summary>
        /// Override the Properties collection and return our custom one.
        /// </summary>
        public override ConfigurationPropertyCollection Properties
        {
            get { return s_properties; }
        }
        #endregion

正如你所看到的,更改基本的上由.NET 2.0提供的对象模型配置。简单地添加setters到配置属性上,允许他们在代码中被修改。ConfigurationElement,这是最终在每个配置类,你可以写的根源,处理所有底层复杂的东西确保修改是验证地、可转换地、有效地保存到.config文件中。要使ConfigurationElementCollection可修改,必须添加方法编辑集合。我们之前的ExampleThingElementCollection类添加一些方法使它可修改:

      #region Methods
        public void Add(ThingElement thing)
        {
            base.BaseAdd(thing);
        }

        public void Remove(string name)
        {
            base.BaseRemove(name);
        }

        public void Remove(ThingElement thing)
        {
            base.BaseRemove(GetElementKey(thing));
        }

        public void Clear()
        {
            base.BaseClear();
        }

        public void RemoveAt(int index)
        {
            base.BaseRemoveAt(index);
        }

        public string GetKey(int index)
        {
            return (string)base.BaseGetKey(index);
        }
        #endregion




一定要记住添加setters到配置元素集合包括的配置元素。添加一些公有的构造器对简化创建和填充配置元素到集合非常有用。一旦你已经做了必要的修改允许你的配置设置能在运行时修改,你可以调用Configuration类的Save()方法。Save()方法有三种不同的重载,允许你控制究竟要保存什么和强迫保存,即使没有变化。

  • Configuration.Save() - 仅保存修改了的值
  • Configuration.Save(ConfigurationSaveMode) - 保存指定类别的修改,如果存在修改
  • Configuration.Save(ConfigurationSaveMode, bool) - 保存指定类别的修改,迫使进行保存,如果第二个参数为true

ConfigurationSaveMode枚举具有以下值:

  • Full - 保存所有配置属性,不管是否有所变化
  • Modified - 保存已修改的属性,即使当前的值和原来是一样的
  • Minimal - 保存已经修改且和原来值不一样的属性

Configuration对象也有一个SaveAs()方法,他有跟Save()方法一样的基本重载。SaveAs()方法要求一个文件名作为第一个参数,表示要将配置文件保存到的路径和文件名。

  

时间: 2024-10-29 21:16:09

揭开.NET 2.0配置之谜(二)的相关文章

揭开.NET 2.0配置之谜(一)

此文是译文,原文是Jon Rista,Unraveling the Mysteries of .NET 2.0 Configuration,由于这篇文章比较长,所以我就分为几部分来翻译. 以前没有翻译过外文,看英文文章倒是也看得懂,现在才发现要翻译出来,而且质量要过关还是挺难的(对我来说).若翻译有不当之处,请不吝赐教,以免此译文误导他人,在此谢过.不废话了,let's start! 致谢:560889223,他帮忙解释了population的翻译问题! 引言 .NET的美妙特点之一是它的XML

揭开.NET 2.0配置之谜(三)

声明:此文是译文,原文是Jon Rista,Unraveling the Mysteries of .NET 2.0 Configuration,由于这篇文章比较长,所以我就分为几部分来翻译,这是此译文的第三部分.若翻译有不当之处,请不吝赐教,以免此译文误导他人,在此谢过. let's go on! 10.配置技巧和窍门 在我研究和实验配置节的时候,我学到一些技巧,可是使他们更容易使用.自定义配置节的某些方面非常乏味,如所有时间一直通过调用ConfigurationManager.GetSect

破解.NET 2.0配置之谜(二)

如果您是.NET 2.0配置的新手,或尚未掌握类型验证和转换的概念,您应该首先阅读以前的文章,可以在以下链接找到: 揭开.NET 2.0配置之谜(一) 揭开.NET 2.0配置之谜(二) 揭开.NET 2.0配置之谜(三) 解码.NET 2.0配置之谜(一) 解码.NET 2.0配置之谜(二) 破解.NET 2.0配置之谜(一) 本文是6.破解.NET 2.0配置之谜(一) 的后续,由于原文比较长,故分成几部分翻译.本部分的主题如下: 3.  Configuration Representati

破解.NET 2.0配置之谜(一)

引言 NET的美妙特点之一是它的XML配置功能.在.NET 1.x时代,常见的应用程设置.数据库连接字符串.ASP.NET Web服务器配置和基本的自定义配置数据可以存储在.config文件中.自定义配置节可以使用一些基本自定义结构,允许少数几种信息存储 在.config文件中.然而更复杂的配置,最常见的实现是自定义XML结构和自定义解析代码.尽管有多种不同性能的方法完成同样的事情,这种代码将变得 相当复杂. 随着.NET 2.0,自己编写(可能很复杂.低性能.繁琐)代码来管理自定义XML配置结

破解.NET 2.0配置之谜(三)

如果您是.NET 2.0配置的新手,或尚未掌握类型验证和转换的概念,您应该首先阅读以前的文章,可以在以下链接找到: 揭开.NET 2.0配置之谜(一) 揭开.NET 2.0配置之谜(二) 揭开.NET 2.0配置之谜(三) 解码.NET 2.0配置之谜(一) 解码.NET 2.0配置之谜(二) 破解.NET 2.0配置之谜(一) 破解.NET 2.0配置之谜(二) 本文要讨论的内容如下: 4.Configuration Metadata Contexts ExeContext WebContex

解码.NET 2.0配置之谜(一)

引言 .NET的美妙特点之一是它的XML配置功能.在.NET 1.x时代,常见的应用程设置.数据库连接字符串.ASP.NET Web服务器配置和基本的自定义配置数据可以存储在.config文件中.自定义配置节可以使用一些基本自定义结构,允许少数几种信息存储 在.config文件中.然而更复杂的配置,最常见的实现是自定义XML结构和自定义解析代码.尽管有多种不同性能的方法完成同样的事情,这种代码将变得 相当复杂. 随着.NET 2.0,自己编写(可能很复杂.低性能.繁琐)代码来管理自定义XML配置

解码.NET 2.0配置之谜(二)

此文是解码.NET 2.0配置之谜(一)的延续,也是揭秘.NET 2.0配置系列中的一部分,点此查看此系列文章.Let's continue! 2.保持类型安全 .NET 平台的出色的地方是其严格的类型安全.此功能有助于书写安全.可靠的代码.任何应用程序中最脆弱的部分是那些访问外部资源的部分,如配置.值得庆幸的 是,.NET 2.0的配置框架包括一些功能,帮助你确保你的配置数据是类型安全的.最初,所有配置数据理解为一个字符串,且在反序列化时必须转化为合适的类型才能使 用..NET 2.0的配置框

关于struts2.0配置返回页面的问题

问题描述 关于struts2.0配置返回页面的问题 struts能不能够动态的指定返回哪张页面?举个例子:比如说,url中带一个参数id,我根据这个id去查,需要返回哪张界面.id有很多,并且数目不固定(会增加),所以没办法在struts的配置文件中枚举.我想了下,用通配符的方式好像是可以实现的,但是跨部门合作,让别人按照这种方式指定文件的路径还是有点蛋疼.. 解决方案 Struts2.0 xml文件的配置(package,namespace,action)Struts2.0 xml文件的配置(

【OGG】OGG的单向复制配置-支持DDL(二)

[OGG]OGG的单向复制配置-支持DDL(二) 一.1  BLOG文档结构图       一.2  前言部分   一.2.1  导读 各位技术爱好者,看完本文后,你可以掌握如下的技能,也可以学到一些其它你所不知道的知识,~O(∩_∩)O~: ① OGG的单向DDL实时复制功能     注意:本篇BLOG中代码部分需要特别关注的地方我都用黄色背景和红色字体来表示,比如下边的例子中,thread 1的最大归档日志号为33,thread 2的最大归档日志号为43是需要特别关注的地方.   List