首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在自定义configSection中指定集合

如何在自定义configSection中指定集合
EN

Stack Overflow用户
提问于 2010-01-05 06:25:16
回答 2查看 6.6K关注 0票数 8

我希望有一个xml配置文件如下所示:

代码语言:javascript
复制
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
    <section name="plugins" type="MyApp.PluginsConfiguration, MyApp"/>
</configSections>

<plugins>
    <use assembly="MyApp.Plugin1.dll" />
    <use assembly="MyApp.Plugin2.dll" />
</plugins>
</configuration>

在我的代码中,我到底应该如何安排PluginsConfigurations、UsePluginCollection和UsePlugin类之间的交互?

我在网上找到了this tutorial,但它会在围绕use集合的插件中引入一个元素,我不需要这个。

This是我到目前为止所拥有的,但它并不完全正确

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2010-01-05 06:29:37

如果MyApp.PluginsConfiguration是一个ConfigurationSection,那么您可以定义一个从ConfigurationElementCollection继承的新类,并使这个新类成为MyApp.PluginsConfiguration的ConfigurationProperty

有关这些类型的一些深入信息,请查看this article。我还blogged about了嵌套的属性,但不是专门针对集合的。

编辑:这里有一些代码。给定的是web.config中的这一位:

代码语言:javascript
复制
<configSections>
    <section name="plugins"
             type="WebApplication1.PluginsConfiguration, WebApplication1"/>
</configSections>
<plugins>
    <use assembly="MyApp.Plugin1.dll"/>
    <use assembly="MyApp.Plugin2.dll"/>
</plugins>

下面是实现这一点的类。请注意,可能需要处理NullReferenceExceptions。

代码语言:javascript
复制
namespace WebApplication1
{
    public class PluginsConfiguration : ConfigurationSection
    {
        private static ConfigurationPropertyCollection properties;
        private static ConfigurationProperty propPlugins;

        static PluginsConfiguration()
        {
            propPlugins = new ConfigurationProperty(null, typeof(PluginsElementCollection),
                                                          null,
                                                          ConfigurationPropertyOptions.IsDefaultCollection);
            properties = new ConfigurationPropertyCollection { propPlugins };
        }

        protected override ConfigurationPropertyCollection Properties
        {
            get
            {
                return properties;
            }
        }

        public PluginsElementCollection Plugins
        {
            get
            {
                return this[propPlugins] as PluginsElementCollection;
            }
        }
    }

    public class PluginsElementCollection : ConfigurationElementCollection
    {
        public PluginsElementCollection()
        {
            properties = new ConfigurationPropertyCollection();
        }

        private static ConfigurationPropertyCollection properties;

        protected override ConfigurationPropertyCollection Properties
        {
            get
            {
                return properties;
            }
        }

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

        protected override string ElementName
        {
            get
            {
                return "use";
            }
        }

        protected override ConfigurationElement CreateNewElement()
        {
            return new PluginsElement();
        }

        protected override object GetElementKey(ConfigurationElement element)
        {
            var elm = element as PluginsElement;
            if (elm == null) throw new ArgumentNullException();
            return elm.AssemblyName;
        }
    }

    public class PluginsElement : ConfigurationElement
    {
        private static ConfigurationPropertyCollection properties;
        private static ConfigurationProperty propAssembly;

        protected override ConfigurationPropertyCollection Properties
        {
            get
            {
                return properties;
            }
        }

        public PluginsElement()
        {
            propAssembly = new ConfigurationProperty("assembly", typeof(string),
                                                          null,
                                                          ConfigurationPropertyOptions.IsKey);
            properties = new ConfigurationPropertyCollection { propAssembly };
        }

        public PluginsElement(string assemblyName)
            : this()
        {
            AssemblyName = assemblyName;
        }

        public string AssemblyName
        {
            get
            {
                return this[propAssembly] as string;
            }
            set
            {
                this[propAssembly] = value;
            }
        }
    }
}

要访问它,下面的代码片段应该会有所帮助:

代码语言:javascript
复制
        var cfg = WebConfigurationManager.GetWebApplicationSection("plugins") as PluginsConfiguration;
        var sb = new StringBuilder();
        foreach(PluginsElement elem in cfg.Plugins)
        {
            sb.AppendFormat("{0}<br/>", elem.AssemblyName);
        }
        testLabel.Text = sb.ToString();

基本上,我们有一个插件来处理ConfigurationSection -element。在这里,我们指定了一个ConfigurationElementCollection属性,并将其声明为默认集合(理论上,您可以在一个根节点下有多个不同的集合)。

PluginsElementCollection实现了ConfigurationElementCollection。ElementName必须是标签的名称,在我们的例子中是"use“。此外,GetElementKey需要被覆盖,并且应该返回一个在条目中唯一的属性。

然后,PluginsElement实现了一个单次使用标记。我们只定义了一个属性: AssemblyName,它被映射到程序集属性。

我并不是完全理解所有这些(特别是ConfigurationElementCollection和它的各种BaseAdd、BaseGet等属性在这里并没有真正探讨),但我可以断言这是可行的:)

而且,它不使用任何属性。我讨厌属性--幸运的是,所有这些属性都可以转换成正确的代码。您可以使用其中一个(或两个都使用)。

票数 17
EN

Stack Overflow用户

发布于 2010-01-05 06:29:07

根据本教程,您可以轻松创建XML配置,如下所示:

代码语言:javascript
复制
<MyApp>
  <Plugins>
    <add assembly="MyApp.Plugin1.dll" />
    <add assembly="MyApp.Plugin2.dll" />
  </Plugins>
</MyApp>

我觉得这完全可以接受。有什么原因这是不可接受的吗?

编辑:

我不确定如何在教程中做到这一点。你需要一些中间元素(比如教程中有“action”)-- George Mauer

好的,试试看这件衣服的尺寸。我可能有一些打字错误,因为我正在复制/粘贴/编辑我使用的一些代码,这些代码可以做你想要的事情,但它应该可以与我上面定义的XML一起工作。

代码语言:javascript
复制
public sealed class MyAppConfiguration : ConfigurationSection
{
    public const string MyAppConfigurationTagName = "MyApp";
    [ConfigurationProperty(MyAppConfigurationTagName, IsRequired = true)]
    public PluginConfigurationCollection Plugins
    {
        get
        {
            return this[MyAppConfigurationTagName] as PluginConfigurationCollection;
        }
        set
        {
            this[MyAppConfigurationTagName] = value;
        }
    }
}

public sealed class PluginConfigurationItem : ConfigurationElement
{
    // repeat this pattern for each additional attribute you want in the <add /> tag. 
    // Only the assembly="foo.dll" portion is defined in this class, and is accessed 
    // via the AssemblyName property. 
    public const string AssemblyPropertyName = "assembly";
    [ConfigurationProperty(AssemblyPropertyName, IsRequired = true, IsKey = true)]
    public string AssemblyName
    {
        get
        {
            return this[AssemblyPropertyName] as string;
        }
        set
        {
            this[AssemblyPropertyName] = value;
        }
    }
}

public class PluginConfigurationCollection : ConfigurationElementCollection, IEnumerable<PluginConfigurationItem>
{
    public const string PluginsElementName = "Plugins";

    protected override ConfigurationElement CreateNewElement()
    {
        return new PluginConfigurationItem();
    }

    protected override object GetElementKey(ConfigurationElement element)
    {
        return ((PluginConfigurationItem)element).AssemblyName;
    }

    protected override string ElementName
    {
        get
        {
            return PluginsElementName;
        }
    }

    // this is extraneous, but I find it very useful for enumerating over a configuration collection in a type-safe manner.
    #region IEnumerable<PluginConfigurationItem> Members

    public new IEnumerator<PluginConfigurationItem> GetEnumerator()
    {
        foreach(PluginConfigurationItem item in (this as IEnumerable))
        {
            yield return item;
        }
    }

    #endregion
}
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2002715

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档