【问题标题】:Linking custom config sections in an app.config在 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>

我有这些标准类:AnimalAnimalCollectionZooZooCollection

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.AnimalsAnimal 实例名称的CSV 字符串。但我想要的是IEnumerable&lt;Animal&gt; 属性。

我该怎么做?

【问题讨论】:

    标签: c# configuration app-config


    【解决方案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\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
    

    我希望这会有所帮助。

    【讨论】:

    • 我假设AnimalSettings.Settings.AnimalList 是你从app.config 得到的?这在我们的案例中是一个问题,因为我们有一个公共/共享程序集(其中包含 Zoo、Animal、类型转换器等),我们将其用于所有客户的应用程序,然后特定客户的应用程序与其在一个单独的程序集中拥有app.config。所以我不能参考那个列表。我希望这不是一个令人困惑的解释!如果一切都在同一个程序集中,这是一个很好的解决方案。
    • 有没有办法以另一种方式实现您的解决方案,我可以提供列表?问题是属性的构造函数不接受任何其他输入。
    • 嗯,这是对上述问题的答案,没有提到任何关于单独程序集的内容。您可以修改设置以打开自定义配置并从该文件返回配置部分。目前它读取本地配置: private static AnimalSettings settings = ConfigurationManager.GetSection("Animals") as AnimalSettings;
    • :-) 我没有在这种情况下尝试过,但我的意思是使用ConfigurationManager.OpenExeConfiguration 这样您就可以读取任何配置文件而不是本地配置文件
    • 是的,不太适合复杂的场景
    猜你喜欢
    • 2011-10-02
    • 2012-10-04
    • 2015-07-05
    • 2011-05-25
    • 2011-11-21
    • 2011-12-10
    • 2010-10-20
    • 2011-11-04
    • 2013-05-19
    相关资源
    最近更新 更多