2012-07-30 24 views
5

Có cách nào để tải cài đặt từ một tệp khác ngoài tệp App.config mặc định khi chạy không? Tôi muốn thực hiện việc này sau khi tệp cấu hình mặc định được tải.Đang tải các thuộc tính.Cài đặt từ một tệp khác tại thời gian chạy

Tôi sử dụng giao diện Settings.Settings trong Visual Studio để tạo tệp App.config cho tôi. Các tập tin cấu hình kết thúc lên tim như thế này:

<?xml version="1.0" encoding="utf-8" ?> 
    <configuration> 
     <configSections> 
      <sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" > 
     <section name="SnipetTester.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" /> 
    </sectionGroup> 
    </configSections> 
     <applicationSettings> 
     <SnipetTester.Properties.Settings> 
      <setting name="SettingSomething" serializeAs="String"> 
      <value>1234</value> 
      </setting> 
     </SnipetTester.Properties.Settings> 
     </applicationSettings> 
    </configuration> 

Trong mã, tôi có thể truy cập vào các thiết lập như thế này:

Console.WriteLine("Default setting value: " + Properties.Settings.Default.SettingSomething); 

Ý tưởng là khi ứng dụng được chạy, tôi nên có thể chỉ định tệp cấu hình tại thời gian chạy và tải ứng dụng tệp cấu hình vào đối tượng Properties.Settings.Default thay vì sử dụng tệp app.config mặc định. Các định dạng của các tập tin cấu hình sẽ giống nhau, nhưng các giá trị của các thiết lập sẽ khác nhau.

Tôi biết cách để thực hiện việc này với ConfigurationManager.OpenExeConfiguration(configFile);. Tuy nhiên, trong các thử nghiệm mà tôi đã chạy, nó không cập nhật đối tượng Properties.Settings.Default để phản ánh các giá trị mới từ tệp cấu hình.


Sau khi suy nghĩ về điều này lâu hơn một chút, tôi đã có thể đưa ra giải pháp mà tôi thích hơn một chút. Tôi chắc chắn nó có một số cạm bẫy, nhưng tôi nghĩ rằng nó sẽ làm việc cho những gì tôi cần nó để làm.

Về cơ bản, lớp Properties.Settings được tạo tự động bởi Visual Studio; nó tạo mã cho lớp cho bạn. Tôi đã có thể tìm thấy nơi mã được tạo ra và thêm một vài cuộc gọi chức năng để tải một tập tin cấu hình riêng của mình. Đây là phần bổ sung của tôi:

internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase 
{ 
    //Parses a config file and loads its settings 
    public void Load(string filename) 
    { 
     System.Xml.Linq.XElement xml = null; 
     try 
     { 
      string text = System.IO.File.ReadAllText(filename); 
      xml = System.Xml.Linq.XElement.Parse(text); 
     } 
     catch 
     { 
      //Pokemon catch statement (gotta catch 'em all) 

      //If some exception occurs while loading the file, 
      //assume either the file was unable to be read or 
      //the config file is not in the right format. 
      //The xml variable will be null and none of the 
      //settings will be loaded. 
     } 

     if(xml != null) 
     { 
      foreach(System.Xml.Linq.XElement currentElement in xml.Elements()) 
      { 
       switch (currentElement.Name.LocalName) 
       { 
        case "userSettings": 
        case "applicationSettings": 
         foreach (System.Xml.Linq.XElement settingNamespace in currentElement.Elements()) 
         { 
          if (settingNamespace.Name.LocalName == "SnipetTester.Properties.Settings") 
          { 
           foreach (System.Xml.Linq.XElement setting in settingNamespace.Elements()) 
           { 
            LoadSetting(setting); 
           } 
          } 
         } 
         break; 
        default: 
         break; 
       } 
      } 
     } 
    } 

    //Loads a setting based on it's xml representation in the config file 
    private void LoadSetting(System.Xml.Linq.XElement setting) 
    { 
     string name = null, type = null, value = null; 

     if (setting.Name.LocalName == "setting") 
     { 
      System.Xml.Linq.XAttribute xName = setting.Attribute("name"); 
      if (xName != null) 
      { 
       name = xName.Value; 
      } 

      System.Xml.Linq.XAttribute xSerialize = setting.Attribute("serializeAs"); 
      if (xSerialize != null) 
      { 
       type = xSerialize.Value; 
      } 

      System.Xml.Linq.XElement xValue = setting.Element("value"); 
      if (xValue != null) 
      { 
       value = xValue.Value; 
      } 
     } 


     if (string.IsNullOrEmpty(name) == false && 
      string.IsNullOrEmpty(type) == false && 
      string.IsNullOrEmpty(value) == false) 
     { 
      switch (name) 
      { 
       //One of the pitfalls is that everytime you add a new 
       //setting to the config file, you will need to add another 
       //case to the switch statement. 
       case "SettingSomething": 
        this[name] = value; 
        break; 
       default: 
        break; 
      } 
     } 
    } 
} 

Mã tôi thêm vào sẽ hiển thị hàm Properties.Settings.Load(string filename). Hàm này chấp nhận một tên tệp cấu hình làm tham số. Nó sẽ phân tích cú pháp tệp và tải lên bất kỳ cài đặt nào mà nó gặp trong tệp cấu hình. Để hoàn nguyên về cấu hình ban đầu, chỉ cần gọi Properties.Settings.Reload().

Hy vọng điều này có thể giúp người khác!

+0

điều này có vẻ thực sự hứa hẹn, nhưng làm cách nào chúng tôi có thể sử dụng các loại – tofutim

Trả lời

0

Xem xét việc sử dụng ExeConfigurationFileMap và ConfigurationManager.OpenMappedExeConfiguration.

Xem Cracking the Mysteries of .Net 2.0 Configuration

Các ExeConfigurationFileMap cho phép bạn cấu hình đặc biệt pathnames chính xác vào máy, exe, chuyển vùng và địa phương cấu hình tác phẩm, tất cả cùng nhau, hoặc từng phần, khi gọi OpenMappedExeConfiguration(). Bạn không bắt buộc phải chỉ định tất cả các tệp nhưng tất cả các tệp sẽ được xác định và hợp nhất khi đối tượng Cấu hình được tạo. Khi sử dụng OpenMappedExeConfiguration, điều quan trọng là phải hiểu rằng tất cả các cấp độ cấu hình vượt qua mức bạn yêu cầu sẽ luôn được hợp nhất . Nếu bạn chỉ định tệp tùy chỉnh và tệp cấu hình cục bộ, nhưng không chỉ định tệp máy và chuyển vùng, máy mặc định và các tệp chuyển vùng sẽ được tìm thấy và hợp nhất với exe và người dùng được chỉ định tệp. Điều này có thể có những hậu quả không mong muốn nếu các tệp được chỉ định không được giữ đúng cách đồng bộ với các tệp mặc định.

1

Nó phụ thuộc vào loại ứng dụng:

  1. Web Application & ứng dụng Windows - sử dụng thuộc tính configSource xml nếu bạn sẵn sàng để lưu trữ các tập tin cấu hình trong cùng một thư mục (hoặc thư mục con) như ứng dụng
  2. Tạo settings provider và cũng triển khai IApplicationSettingsProvider. Các mẫu herehere. Bạn cũng có thể cần sử dụng giao diện IConfigurationManagerInternal để thay thế trình quản lý cấu hình .NET mặc định. Khi triển khai nhà cung cấp, đừng quên tạo sự khác biệt giữa cài đặt người dùng và cài đặt ứng dụng cũng như hồ sơ chuyển vùng.

Nếu bạn muốn bắt đầu một cách nhanh chóng chỉ biên soạn lại lớp LocalFileSettingsProvider (nhà cung cấp các thiết lập mặc định) và thay đổi nó yêu cầu của bạn (bạn có thể tìm thấy một số mã useles và có thể cần phải sao chép tất cả các lớp học mà nó phụ thuộc).

Chúc may mắn

0

Bạn có thể bao gồm các loại để bạn không cần phải cập nhật nguồn theo cách thủ công mọi lúc.

`riêng void LoadSetting (System.Xml.Linq.XElement setting) { string name = null, type = null; giá trị chuỗi = null;

 if (setting.Name.LocalName == "setting") 
     { 
      System.Xml.Linq.XAttribute xName = setting.Attribute("name"); 
      if (xName != null) 
      { 
       name = xName.Value; 
      } 

      System.Xml.Linq.XAttribute xSerialize = setting.Attribute("serializeAs"); 
      if (xSerialize != null) 
      { 
       type = xSerialize.Value; 
      } 

      System.Xml.Linq.XElement xValue = setting.Element("value"); 
      if (xValue != null) 
      { 
       if (this[name].GetType() == typeof(System.Collections.Specialized.StringCollection)) 
       { 
        foreach (string s in xValue.Element("ArrayOfString").Elements()) 
        { 
         if (!((System.Collections.Specialized.StringCollection)this[name]).Contains(s)) 
          ((System.Collections.Specialized.StringCollection)this[name]).Add(s); 
        } 
       } 
       else 
       { 
        value = xValue.Value; 
       } 

       if (this[name].GetType() == typeof(int)) 
       { 
        this[name] = int.Parse(value); 
       } 
       else if (this[name].GetType() == typeof(bool)) 
       { 
        this[name] = bool.Parse(value); 
       } 
       else 
       { 
        this[name] = value; 
       } 

      } 
     }` 
+0

là có thể xử lý tùy chọn này cho loại tùy ý – tofutim

Các vấn đề liên quan