C# 在.NET4中包含集合的简单自定义配置节
我正试图为.NET4应用程序编写一个非常简单的自定义配置部分。我的目标是:C# 在.NET4中包含集合的简单自定义配置节,c#,.net,.net-4.0,system.configuration,C#,.net,.net 4.0,System.configuration,我正试图为.NET4应用程序编写一个非常简单的自定义配置部分。我的目标是: <configuration> <configSections> <section name="myServices" type="My.ConfigSection, My.Assembly" /> </configSections> <myServices> <add name="First" /> <ad
<configuration>
<configSections>
<section name="myServices" type="My.ConfigSection, My.Assembly" />
</configSections>
<myServices>
<add name="First" />
<add name="Second" />
</myServices>
</configuration>
接下来,集合类本身。这是一种类型的
最后是集合中元素的类。现在,这个类只有一个属性,但以后会有更多属性(这使我无法使用)
你似乎错过了类似的东西
[ConfigurationProperty("urls", IsDefaultCollection = false)]
[ConfigurationCollection(typeof(UrlsCollection),
AddItemName = "add",
ClearItemsName = "clear",
RemoveItemName = "remove")]
有关更多信息,请参见好的,我找到了看似随机的修复。与此相反:
[ConfigurationProperty("", IsDefaultCollection = true)]
public ProvisiorServiceSettingsCollection ProvisiorServices
{ ... }
你应使用:
[ConfigurationProperty("", Options = ConfigurationPropertyOptions.IsDefaultCollection)]
public ProvisiorServiceSettingsCollection ProvisiorServices
{ ... }
不知道两者有什么区别。对我来说,他们看起来惊人地相似。。。或者至少,没有任何关于为什么一个比另一个更受欢迎的建议。因为我在这方面花了很多时间,所以我想添加一个我刚刚在这个提交中实现的真实示例: 以下是我的web.config的目标(我能够实现): 在这种情况下,我的web.config如下所示:
<?xml version="1.0" encoding="utf-8" ?>
<templates>
<template name="Responsive" path="~/Views/Formulate/Responsive.Bootstrap.Angular.cshtml" />
</templates>
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<sectionGroup name="formulateConfiguration">
<section name="templates" type="formulate.app.Configuration.TemplatesConfigSection, formulate.app" requirePermission="false"/>
</sectionGroup>
</configSections>
<formulateConfiguration>
<templates configSource="config\Formulate\templates.config"/>
</formulateConfiguration>
</configuration>
我想我应该提到,如果其他人试图将其添加到外部文件中(外部文件中的根级别项与web.config中的外部化元素相同,这有点不直观)。已经尝试过了,但没有成功。我找到了答案,将很快添加。另一个选项-查看论坛帖子上的最后一个条目。在问这个问题之前,我已经用我所有的谷歌技能找到了答案:)但是很高兴知道它是如何工作的-在接下来的几周里会有类似的成就,所以谢谢:-)这很奇怪。
IsDefaultCollection
和选项都适用于我。但属性名必须为空字符串。查看ConfigurationPropertyAttribute.cs的参考源,IsDefaultCollection属性只是Options flags属性的包装器-这比OP的原始代码和修复程序简单,可能是由于.NET在此期间发生了更改。请注意,使用.NET核心配置(以上所有内容仅适用于旧的.NET framework配置)时,使用
[ConfigurationProperty("", Options = ConfigurationPropertyOptions.IsDefaultCollection)]
public ProvisiorServiceSettingsCollection ProvisiorServices
{ ... }
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<sectionGroup name="formulateConfiguration">
<section name="templates" type="formulate.app.Configuration.TemplatesConfigSection, formulate.app" requirePermission="false"/>
</sectionGroup>
</configSections>
<formulateConfiguration>
<templates>
<template name="Responsive" path="~/Views/Formulate/Responsive.Bootstrap.Angular.cshtml" />
</templates>
</formulateConfiguration>
</configuration>
namespace formulate.app.Configuration
{
// Namespaces.
using System.Configuration;
/// <summary>
/// A configuration section for Formulate templates.
/// </summary>
public class TemplatesConfigSection : ConfigurationSection
{
#region Properties
/// <summary>
/// The templates in this configuration section.
/// </summary>
[ConfigurationProperty("", IsDefaultCollection = true)]
[ConfigurationCollection(typeof(TemplateCollection), AddItemName = "template")]
public TemplateCollection Templates
{
get
{
return base[""] as TemplateCollection;
}
}
#endregion
}
}
namespace formulate.app.Configuration
{
// Namespaces.
using System.Configuration;
/// <summary>
/// A collection of templates from the configuration.
/// </summary>
[ConfigurationCollection(typeof(TemplateElement))]
public class TemplateCollection : ConfigurationElementCollection
{
#region Methods
/// <summary>
/// Creates a new template element.
/// </summary>
/// <returns>The template element.</returns>
protected override ConfigurationElement CreateNewElement()
{
return new TemplateElement();
}
/// <summary>
/// Gets the key for an element.
/// </summary>
/// <param name="element">The element.</param>
/// <returns>The key.</returns>
protected override object GetElementKey(ConfigurationElement element)
{
return (element as TemplateElement).Name;
}
#endregion
}
}
namespace formulate.app.Configuration
{
// Namespaces.
using System.Configuration;
/// <summary>
/// A "template" configuration element.
/// </summary>
public class TemplateElement : ConfigurationElement
{
#region Constants
private const string DefaultPath = "~/*Replace Me*.cshtml";
#endregion
#region Properties
/// <summary>
/// The name of the template.
/// </summary>
[ConfigurationProperty("name", IsRequired = true)]
public string Name
{
get
{
return base["name"] as string;
}
set
{
this["name"] = value;
}
}
/// <summary>
/// The path to this template.
/// </summary>
/// <remarks>
/// Should start with "~" and end with ".cshtml".
/// </remarks>
[ConfigurationProperty("path", IsRequired = true, DefaultValue = DefaultPath)]
[RegexStringValidator(@"^~.*\.[cC][sS][hH][tT][mM][lL]$")]
public string Path
{
get
{
var result = base["path"] as string;
return result == DefaultPath ? null : result;
}
set
{
this["path"] = value;
}
}
#endregion
}
}
<?xml version="1.0" encoding="utf-8" ?>
<templates>
<template name="Responsive" path="~/Views/Formulate/Responsive.Bootstrap.Angular.cshtml" />
</templates>
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<sectionGroup name="formulateConfiguration">
<section name="templates" type="formulate.app.Configuration.TemplatesConfigSection, formulate.app" requirePermission="false"/>
</sectionGroup>
</configSections>
<formulateConfiguration>
<templates configSource="config\Formulate\templates.config"/>
</formulateConfiguration>
</configuration>