Phần app.config tùy chỉnh với danh sách các phần tử “thêm” đơn giản


88

Làm cách nào để tạo phần app.config tùy chỉnh chỉ là một danh sách các addphần tử đơn giản ?

Tôi đã tìm thấy một vài ví dụ (ví dụ: Cách tạo phần cấu hình tùy chỉnh trong app.config? ) Cho các phần tùy chỉnh trông như thế này:

<RegisterCompanies>
  <Companies>
    <Company name="Tata Motors" code="Tata"/>
    <Company name="Honda Motors" code="Honda"/>
  </Companies>
</RegisterCompanies>

Nhưng làm cách nào để tránh phần tử thu thập bổ sung ("Công ty") để nó trông giống với phần appSettingsconnectionStrings? Nói cách khác, tôi muốn:

<registerCompanies>
  <add name="Tata Motors" code="Tata"/>
  <add name="Honda Motors" code="Honda"/>
</registerCompanies>

Câu trả lời:


115

Ví dụ đầy đủ với mã dựa trên tệp cấu hình OP:

<configuration>
    <configSections>
        <section name="registerCompanies" 
                 type="My.MyConfigSection, My.Assembly" />
    </configSections>
    <registerCompanies>
        <add name="Tata Motors" code="Tata"/>
        <add name="Honda Motors" code="Honda"/>
    </registerCompanies>
</configuration>

Đây là mã mẫu để triển khai phần cấu hình tùy chỉnh với bộ sưu tập thu gọn

using System.Configuration;
namespace My {
public class MyConfigSection : ConfigurationSection {
    [ConfigurationProperty("", IsRequired = true, IsDefaultCollection = true)]
    public MyConfigInstanceCollection Instances {
        get { return (MyConfigInstanceCollection)this[""]; }
        set { this[""] = value; }
    }
}
public class MyConfigInstanceCollection : ConfigurationElementCollection {
    protected override ConfigurationElement CreateNewElement() {
        return new MyConfigInstanceElement();
    }

    protected override object GetElementKey(ConfigurationElement element) {
        //set to whatever Element Property you want to use for a key
        return ((MyConfigInstanceElement)element).Name;
    }
}

public class MyConfigInstanceElement : ConfigurationElement {
    //Make sure to set IsKey=true for property exposed as the GetElementKey above
    [ConfigurationProperty("name", IsKey = true, IsRequired = true)]
    public string Name {
        get { return (string) base["name"]; }
        set { base["name"] = value; }
    }

    [ConfigurationProperty("code", IsRequired = true)]
    public string Code {
        get { return (string) base["code"]; }
        set { base["code"] = value; }
    } } }

Đây là một ví dụ về cách truy cập thông tin cấu hình từ mã.

var config = ConfigurationManager.GetSection("registerCompanies") 
                 as MyConfigSection;

Console.WriteLine(config["Tata Motors"].Code);
foreach (var e in config.Instances) { 
   Console.WriteLine("Name: {0}, Code: {1}", e.Name, e.Code); 
}

@Jay Walker làm thế nào để bạn truy cập vào mục mà bạn cần, tức là: - config.Instances ["Tata Motors"] có thể làm điều này không?
Simon

2
Nên chỉ ra thẻ <configSection>nên ở ngay sau <configuration>thẻ để nó hoạt động!
Vedran Kopanja

2
Cũng nên chỉ ra rằng <add là bắt buộc. Tạo thẻ <tùy chỉnh của riêng bạn không hoạt động với câu trả lời này
Steve's a D

8
AFAIK - mã này "config [" Tata Motors "]" sẽ không biên dịch b / c trình chỉ mục của cấu hình được bảo vệ bên trong. bạn sẽ phải tự mình tìm cách liệt kê các mục trong bộ sưu tập.
CedricB

1
@JayWalker đều tốt. "My.MyConfiguration, My.Assembly" trong ví dụ của bạn cho loại phần ném cho tôi. Tôi chỉ cần sử dụng "MyAssembly.MyConfiguration, MyAssembly" cho những gì tôi đang cố gắng.
Glen

38

Không cần phần cấu hình tùy chỉnh.

App.Config

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <configSections>
        <section name="YourAppSettings" type="System.Configuration.AppSettingsSection, System.Configuration, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
    </configSections>
    <!-- value attribute is optional. omit if you just want a list of 'keys' -->
    <YourAppSettings>
        <add key="one" value="1" />
        <add key="two" value="2"/>
        <add key="three" value="3"/>
        <add key="duplicate" value="aa"/>
        <add key="duplicate" value="bb"/>
    </YourAppSettings>
</configuration>

Lấy lại

// This casts to a NameValueCollection because the section is defined as a 
/// AppSettingsSection in the configSections.
NameValueCollection settingCollection = 
    (NameValueCollection)ConfigurationManager.GetSection("YourAppSettings");

var items = settingCollection.Count;
Debug.Assert(items == 4); // no duplicates... the last one wins.
Debug.Assert(settingCollection["duplicate"] == "bb");

// Just keys as per original question? done... use em.
string[] allKeys = settingCollection.AllKeys;

// maybe you did want key/value pairs. This is flexible to accommodate both.
foreach (string key in allKeys)
{
    Console.WriteLine(key + " : " + settingCollection[key]);
}

1
Tôi đoán nó không trả lời đúng câu hỏi của OP, nhưng tôi nghĩ đó là một giải pháp hợp lệ và đơn giản hơn nhiều. Ít nhất nó đã giúp tôi!
styl0r

2
@ styl0r bạn nói đúng. nó không hoàn toàn trả lời nó. Nếu bạn phải sử dụng tên / mã thuộc tính thay vì khóa / giá trị giải pháp của tôi, bạn phải sử dụng một phần thực sự tùy chỉnh. Tuy nhiên, tôi cho rằng bạn đang kiểm soát tệp cấu hình và có nhiều việc tốt hơn phải làm hơn là tạo một lớp tùy chỉnh.
JJS

4
Rất đơn giản và sạch sẽ! Không cần thêm bất kỳ phần tùy chỉnh / phần tử bloatware nào.
Ondřej

2
Bạn cũng có thể cập nhật lên Phiên bản = 4.0.0.0 nếu bạn muốn chỉ bằng cách thay đổi số phiên bản. Đây là câu trả lời tốt nhất imo nếu bạn chỉ cần thêm danh sách đơn giản. Điều tương tự cũng có thể được thực hiện cho "System.Configuration.ConnectionStringsSection", mặc dù các bản sao được xử lý hơi khác so với cài đặt ứng dụng.
Sharpiro

@Sharpiro bạn có gặp sự cố với phiên bản lắp ráp không? Tôi nghĩ rằng liên kết lắp ráp sẽ bắt kịp tốc độ, ngay cả đối với các phiên bản mới hơn của khung.
JJS

22

Dựa trên câu trả lời của Jay Walker ở trên, đây là một ví dụ hoạt động hoàn chỉnh giúp bổ sung khả năng lập chỉ mục:

<configuration>
    <configSections>
        <section name="registerCompanies" 
                 type="My.MyConfigSection, My.Assembly" />
    </configSections>
    <registerCompanies>
        <add name="Tata Motors" code="Tata"/>
        <add name="Honda Motors" code="Honda"/>
    </registerCompanies>
</configuration>

Đây là mã mẫu để triển khai phần cấu hình tùy chỉnh với bộ sưu tập thu gọn

using System.Configuration;
using System.Linq;
namespace My
{
   public class MyConfigSection : ConfigurationSection
   {
      [ConfigurationProperty("", IsRequired = true, IsDefaultCollection = true)]
      public MyConfigInstanceCollection Instances
      {
         get { return (MyConfigInstanceCollection)this[""]; }
         set { this[""] = value; }
      }
   }
   public class MyConfigInstanceCollection : ConfigurationElementCollection
   {
      protected override ConfigurationElement CreateNewElement()
      {
         return new MyConfigInstanceElement();
      }

      protected override object GetElementKey(ConfigurationElement element)
      {
         //set to whatever Element Property you want to use for a key
         return ((MyConfigInstanceElement)element).Name;
      }

      public new MyConfigInstanceElement this[string elementName]
      {
         get
         {
            return this.OfType<MyConfigInstanceElement>().FirstOrDefault(item => item.Name == elementName);
         }
      }
   }

   public class MyConfigInstanceElement : ConfigurationElement
   {
      //Make sure to set IsKey=true for property exposed as the GetElementKey above
      [ConfigurationProperty("name", IsKey = true, IsRequired = true)]
      public string Name
      {
         get { return (string)base["name"]; }
         set { base["name"] = value; }
      }

      [ConfigurationProperty("code", IsRequired = true)]
      public string Code
      {
         get { return (string)base["code"]; }
         set { base["code"] = value; }
      }
   }
}

Đây là một ví dụ về cách truy cập thông tin cấu hình từ mã.

MyConfigSection config = 
   ConfigurationManager.GetSection("registerCompanies") as MyConfigSection;

Console.WriteLine(config.Instances["Honda Motors"].Code);
foreach (MyConfigInstanceElement e in config.Instances)
{
   Console.WriteLine("Name: {0}, Code: {1}", e.Name, e.Code);
}

2
Điều đó thật tuyệt. Bây giờ chúng ta chỉ cần mã ví dụ để cập nhật, thêm và xóa một Phiên bản.
Scott Hutchinson

1
Cảm ơn giải pháp của bạn! Ai đã làm điều này ở MS ... điều này thực sự không cần thiết phải phức tạp.
Chuyển 386

8

Dựa trên câu trả lời của Jay Walker, việc truy cập các phần tử cần được thực hiện bằng cách lặp lại qua bộ sưu tập "Phiên bản". I E.

var config = ConfigurationManager.GetSection("registerCompanies") 
                 as MyConfigSection;

foreach (MyConfigInstanceElement e in config.Instances) { 
   Console.WriteLine("Name: {0}, Code: {1}", e.Name, e.Code); 
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.