在 app.config 中链接自定义配置部分
Linking custom config sections in an app.config
我的 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>
属性.
我该怎么做?
基本上您需要的是提供一种将逗号分隔的字符串值转换为 IEnumerable 的方法。这可以通过提供自定义 TypeConverter 来实现。所以你的 Zoo class 看起来像这样:
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\t{animal.Age}\t\t{animal.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\t{animal.Age}\t\t{animal.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
希望对您有所帮助。
我的 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>
属性.
我该怎么做?
基本上您需要的是提供一种将逗号分隔的字符串值转换为 IEnumerable 的方法。这可以通过提供自定义 TypeConverter 来实现。所以你的 Zoo class 看起来像这样:
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\t{animal.Age}\t\t{animal.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\t{animal.Age}\t\t{animal.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
希望对您有所帮助。