在 app.config 中链接自定义配置部分
Posted
技术标签:
【中文标题】在 app.config 中链接自定义配置部分【英文标题】:Linking custom config sections in an app.config 【发布时间】:2015-08-03 00:30:11 【问题描述】:我的app.config
有这些自定义部分:
<Animals>
<add Type="Elephant" Name="Dumbo" Age="22" />
<add Type="Giraffe" Name="Shorty" Age="5" />
<add Type="Giraffe" Name="Mike" Age="7" />
<add Type="Lion" Name="Shaggy" Age="2" />
</Animals>
<Zoos>
<add Name="New York Zoo" Animals="Dumbo,Shorty" />
<add Name="Paris Zoo" Animals="Mike,Shaggy" />
</Zoos>
我有这些标准类:Animal
、AnimalCollection
、Zoo
、ZooCollection
。
Zoo
完全符合预期,如下所示:
public class Zoo : ConfigurationElement
[ConfigurationProperty("Name", IsRequired=true)]
public string Name get return base["Name"] as string;
// I don't want this:
[ConfigurationProperty("Animals", IsRequired=true)]
public string Animals get return base["Animals"] as string;
// I want something like this:
/*
[ConfigurationProperty("Animals", IsRequired=true)]
public IEnumerable<Animal> Animals get return ...?
*/
所以Zoo.Animals
是Animal
实例名称的CSV 字符串。但我想要的是IEnumerable<Animal>
属性。
我该怎么做?
【问题讨论】:
【参考方案1】:基本上,您需要提供一种将逗号分隔的字符串值转换为 IEnumerable 的方法。这可以通过提供自定义 TypeConverter 来实现。所以你的 Zoo 类应该是这样的:
public class Zoo : ConfigurationElement
[ConfigurationProperty("Name")]
public string Name
get return (string)base["Name"];
[TypeConverter(typeof(AnimalConverter))]
[ConfigurationProperty("Animals")]
public IEnumerable<Animal> Animals
get return (IEnumerable<Animal>)base["Animals"];
AnimalConverter 是:
public class AnimalConverter : TypeConverter
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
AnimalCollection animals = AnimalSettings.Settings.AnimalList;
List<Animal> result = new List<Animal>();
foreach (string animalName in value.ToString().Split(','))
foreach (Animal animal in animals)
if (animalName == animal.Name)
result.Add(animal);
return result;
当我使用控制台应用对其进行测试时:
class Program
static void Main(string[] args)
AnimalCollection animals = AnimalSettings.Settings.AnimalList;
foreach (Animal animal in animals)
Console.WriteLine($"animal.Name\t\tanimal.Age\t\tanimal.Type");
Console.WriteLine();
ZooCollection zoos = ZooSettings.Settings.ZooList;
foreach (Zoo zoo in zoos)
Console.WriteLine(zoo.Name);
foreach (Animal animal in zoo.Animals)
Console.WriteLine($"animal.Name\t\tanimal.Age\t\tanimal.Type" );
Console.WriteLine();
我得到了这些结果:
Dumbo 22 Elephant
Shorty 5 Giraffe
Mike 7 Giraffe
Shaggy 2 Lion
New York Zoo
Dumbo 22 Elephant
Shorty 5 Giraffe
Paris Zoo
Mike 7 Giraffe
Shaggy 2 Lion
我希望这会有所帮助。
【讨论】:
我假设AnimalSettings.Settings.AnimalList
是你从app.config
得到的?这在我们的案例中是一个问题,因为我们有一个公共/共享程序集(其中包含 Zoo、Animal、类型转换器等),我们将其用于所有客户的应用程序,然后特定客户的应用程序与其在一个单独的程序集中拥有app.config
。所以我不能参考那个列表。我希望这不是一个令人困惑的解释!如果一切都在同一个程序集中,这是一个很好的解决方案。
有没有办法以另一种方式实现您的解决方案,我可以提供列表?问题是属性的构造函数不接受任何其他输入。
嗯,这是对上述问题的答案,没有提到任何关于单独程序集的内容。您可以修改设置以打开自定义配置并从该文件返回配置部分。目前它读取本地配置: private static AnimalSettings settings = ConfigurationManager.GetSection("Animals") as AnimalSettings;
:-) 我没有在这种情况下尝试过,但我的意思是使用ConfigurationManager.OpenExeConfiguration 这样您就可以读取任何配置文件而不是本地配置文件
是的,不太适合复杂的场景以上是关于在 app.config 中链接自定义配置部分的主要内容,如果未能解决你的问题,请参考以下文章