• Thứ Năm, 23/03/2006 10:17 (GMT+7)

    Thiết lập cấu hình cho ứng dụng .Net

    Đa phần ứng dụng thực tế đều có nhu cầu lưu trữ và truy xuất thông tin cấu hình hệ thống. Người ta thường lưu trữ các thông tin này trong tập tin *.ini hoặc trong một dạng tập tin có cấu trúc do người phát triển ứng dụng quy định.

    Trong ứng dụng viết trên nền .NET, thông tin về cấu hình được chứa trong tập tin App.Config (dùng cho Windows Application) và Web.Config (dùng cho ASP.NET Web Application) dựa trên định dạng XML. Để đơn giản, tôi sẽ gọi đây là tập tin cấu hình.

    Tập Tin Cấu Hình

     

    Mối liên hệ giữa configuration section, configuration declaration (section) và configuration settings (tags) 

    Tập tin cấu hình là một tập tin dạng văn bản (text), dựa trên chuẩn XML. Tập tin này được chia thành nhiều phần khác nhau, gọi là configuration section, cho phép đặt thông tin cấu hình cho từng phần khác nhau của ứng dụng như Debugging, Profiling, Security,... Trong phạm vi bài viết này, chúng ta chỉ quan tâm đến phần thông tin cấu hình cho phép chúng ta, với vai trò là người phát triển ứng dụng, có thể đưa thông tin vào tập tin này và truy xuất thông tin lúc chương trình thực thi.

    Mỗi phần thông tin cấu hình đưa vào tập tin cấu hình sẽ gồm 2 phần:

    - Phần khai báo (configuration declaration): quy định lớp đối tượng (section handler) nào sẽ đảm nhận việc đọc thông tin từ configuration settings tương ứng.

    - Phần dữ liệu thực sự (configuration settings): chứa cấu trúc dữ liệu mà ta muốn thêm vào tập tin cấu hình.
    Đối với Windows Application, tập tin cấu hình thường nằm trong cùng thư mục với chương trình và những thông tin cấu hình này sẽ ảnh hưởng đến toàn bộ hoạt động của chương trình. Tuy nhiên, khi bạn cài đặt .NET Framework, còn có một tập tin cấu hình ảnh hưởng đến tất cả các ứng dụng chạy trên máy. Bạn có thể tìm thấy tập tin này trong thư mục cài đặt .NET Framework tại $WINDIR\Microsoft.NET\Framework\v1.1.4322\CONFIG\machine.config.

    Lúc thực thi, ứng dụng sẽ ưu tiên đọc thông tin cấu hình trong tập tin machine.config trước, sau đó mới tới tập tin cấu hình. Dựa trên thông tin trong configuration section, kết quả thông tin cấu hình sau cùng sẽ là:

    - Kết hợp tập tin machine.config và tập tin cấu hình.

    - Thông tin cấu hình ở tập tin cấu hình chiếm độ ưu tiên.

    Thông Tin Cấu Hình

    .NET cung cấp sẵn một configuration section gọi là appSettings. Phần này được khai báo trong tập tin machine.config như sau:

    Phần configuration declaration trong tập tin machine.config

    <section name="appSettings"

    type="System.Configuration.NameValueFileSectionHandler,

    System, Version=1.0.5000.0, Culture=neutral,

    PublicKeyToken=b77a5c561934e089"/>

    Phần configuration settings sẽ được đặt lồng trong appSettings. Thông tin này được đặt trong tập tin App.Config hoặc Web.Config.

    <appSettings>

    <add key="author" value="Ngô Đình Nghĩa"/>

    <add key="article" value="Thiết Lập Cấu Hình Cho Ứng Dụng .NET"/>

    </appSettings>

    Mặc dù .NET cung cấp phần chứa thông tin ở dạng Key-Value trong <appSettings> như bạn thấy ở trên, nhưng phần này chỉ thích hợp nếu như bạn có một vài cặp Key-Value. Tuy nhiên, nếu ứng dụng của bạn có nhiều thông tin trong <appSettings> sẽ dẫn đến việc khó tổ chức thông tin cấu hình theo một dạng cấu trúc nào đó. Vì vậy, .NET cho phép bạn có thể định nghĩa phần thông tin cấu hình riêng theo ý mình.

    .NET cho phép định nghĩa configuration section trong một thẻ XML theo cấu trúc sau:

    <configSections>

    <section name="sampleSection"

    type="System.Configuration.SingleTagSectionHandler" />

    </configSections>

    Như trình bày ở trên, mỗi configuration section sẽ bao gồm 2 phần declaration và settings. Phần declaration tương ứng với thẻ <section> ở trên chứa 2 thuộc tính:

    • name:
    thuộc tính này chứa tên của thẻ trong phần configuration settings mà section handler sẽ đọc thông tin từ đó.

    • type:
    thuộc tính này chứa tên của lớp (còn gọi là section handler) phụ trách việc đọc thông tin từ trong configuration settings.

    Phần khai báo chỉ ra rằng thông tin trong phần configuration settings sẽ được đọc thông qua System.Configuration.NameValueFileSectionHandler section handler.

    .NET cung cấp sẵn một số lớp trong System.Configuration mà ta có thể dùng để khai báo cho thuộc tính type ở trên.

    Chúng ta cũng có thể dùng thẻ <sectionGroup> được .NET cung cấp để thêm nhiều thông tin chi tiết vào trong phần khai báo:

    <configSections>

    <sectionGroup name="DatabaseSettings">

    <sectionGroup name="ConnectionSettings">

    <section .../>
    ...
    ...

    </sectionGroup>

    </sectionGroup>
    ...
    ...

    </configSections>

    Truy xuất cấu hình

    Giả sử rằng bạn có một configuration settings chứa thông tin cấu hình dạng cặp Key-Value như sau:

    <!--// configuration settings -->

    <siteSettings>

    <common>

    <emails>

    <add key="adminmail" value="administrator@somedomain.com"/>

    <add key="salesmail" value="sales@somedomain.com"/>

    <add key="supportmail" value="support@somedomain.com"/>

    <add key="admail" value="advertising@somedomain.com"/>

    </emails>

    </common>

    </siteSettings>

    Bây giờ, điều bạn cần làm là cho ứng dụng biết phần configuration settings này sẽ được xử lý như thế nào. .NET cung cấp sẵn một section handler gọi là NameValueSectionHandler nằm trong System.Configuration có nhiệm vụ xử lý các section chứa thông tin ở dạng cặp Key-Value. Chúng ta sẽ dùng section handler này xử lý section mà chúng ta vừa định nghĩa ở trên.

    <!--// configuration declaration -->

    <configuration>

    <configSections>

    <sectionGroup name="siteSettings">

    <sectionGroup name="common">

    <section name="emails"

    type="System.Configuration.NameValueSectionHandler, System"/>

    </sectionGroup>

    </sectionGroup>

    </configSections>
    ...

    </configuration>

    Một khi đã đặt configuration settings and configuration declaration vào trong tập tin cấu hình, bạn có thể truy xuất thông tin đó từ trong ứng dụng như sau:
    ...

    NameValueCollection nvc = (NameValueCollection)

    ConfigurationSettings.GetConfig("siteSettings/common/emails");

    Label1.Text = nvc["salesmail"];

    Label2.Text = nvc["supportmail"];

    Label3.Text = nvc["adminmail"];
    ...

    Một ví dụ thứ hai về cách dùng SingleTagSectionHandler. Giả sử bạn đưa thông tin vào tập tin cấu hình với cấu trúc như sau:

    <configuration>

    <sampleSection setting1="value one" setting2="value two" setting3="third value" />

    </configuration>

    Bạn có thể thêm configuration declaration như sau:

    <configuration>

    <configSections>

    <section name="sampleSection"

    type="System.Configuration.SingleTagSectionHandler" />

    </configSections>

    </configuration>

    Trong ứng dụng, bạn có thể dùng đoạn code sau để truy xuất thông tin:

    using System;

    using System.Collections;

    using System.Configuration;

    public class MyConfigurationReader

    {

    public void ReadMySettings()

    {

    IDictionary sampleTable;

    string value1;

    string value2;

    string value3;

    sampleTable = (IDictionary) ConfigurationSettings.GetConfig("sampleSection");

    value1 = sampleTable("setting1").ToString();

    value2 = sampleTable("setting2").ToString();

    value3 = sampleTable("setting3").ToString();

    }

    }

    Để khai báo một section handler, bạn phải tạo ra một lớp đối tượng cài đặt giao diện System.Configuration.IconfigurationSectionHandler.

    public class MyConfigHandler: IconfigurationSectionHandler

    {

    ...

    }

    Có một method mà bạn phải định nghĩa khi cài đặt giao diện IconfigurationSectionHandler:

    object Create (object parent, object configContext, XmlNode section)

    • parent - configuration settings mà là cha của configuration section.

    • configContext - một biến kiểu HttpConfigurationContext, khi hàm Create được gọi từ ASP.NET configuration system. Bằng không, tham số này sẽ được gán giá trị là null (C#) hoặc Nothing (VB.NET).

    • section - XmlNode bao gồm thông tin cấu hình. Tham số này cho phép truy cập trực tiếp đến nội dung XML của configuration section.

    • Giá trị trả về - Hàm này trả về một lớp đối tượng do bạn quy định.

    Dưới đây là một ví dụ về việc khai báo lớp SectionHandler để đọc thông tin cấu hình theo cấu trúc bạn quy định:

    namespace ConfigSectionProj

    {

    public class DatabaseInfoConfigHandler: IConfigurationSectionHandler

    {

    public DatabaseInfoConfigHandler(){}

    public object Create(object parent, object configContext, System.Xml.XmlNode section)

    {

    DatabaseInfo objDB = new DatabaseInfo();

    objDB.Server = section.SelectSingleNode("server").InnerText;

    objDB.Database = section.SelectSingleNode("database").InnerText;

    objDB.User = section.SelectSingleNode("user").InnerText;

    objDB.Password = section.SelectSingleNode("password").InnerText;

    return objDB;

    }

    }

    }// end namespace

    DatabaseInfo là lớp đối tượng dùng để định nghĩa cấu trúc của configuration section. Lớp này chứa các phần tử tương ứng với các thông tin trong configuration settings.

    // declare DatabaseInfo class

    namespace ConfigSectionProj

    {

    public class DatabaseInfo

    {

    // public members

    public string Server = string.Empty;

    public string Database = string.Empty;

    public string User = string.Empty;

    public string Password = string.Empty;

    // constructor

    public DatabaseInfo(){}

    }

    }// end namespace

    Sau khi tạo xong lớp section handler cho configuration section, bạn có thể khai báo section này trong tập tin cấu hình như sau:

    <!--// configuration declaration -->

    <configSections>

    ...

    <sectionGroup name="databaseProviderInfo">

    <section name="databaseInfo"

    type="ConfigSectionProj.DatabaseInfoConfigHandler,ConfigSectionProj"/>

    </sectionGroup>

    ...

    </configSections>

    Trong đó, ConfigSectionProj là tên của namespace.

    Sau đó bạn có thể khai báo phần configuration settings trong tập tin cấu hình như sau:

    <!--// configuration settings -->

    <databaseProviderInfo>

    <DatabaseInfo>

    <database>Northwind</database>

    <server>localhost</server>

    <user>testuser</user>

    <password>testpassword</password>

    </DatabaseInfo>

    </databaseProviderInfo>

    Để đọc section databaseInfo từ trong tập tin App.config hoặc Web.Config, bạn có thể dùng hàm ConfigurationSettings.GetConfig với cú pháp như sau:
    DatabaseInfo obj =

    (DatabaseInfo)ConfigurationSettings.GetConfig("databaseProviderInfo/databaseInfo");

    Hàm ConfigurationSettings.GetConfig sẽ trả về một lớp đối tượng cho configuration section mà bạn đã định nghĩa.

    Lời Kết

    Hầu hết các ứng dụng đều có nhu cầu chứa thông tin chung cho toàn bộ ứng dụng ở một nơi lưu trữ nào đó, có thể là trong tập tin ini hay registry. Việc lựa chọn cách thức lưu thông tin ở đâu là tùy thuộc vào người phát triển ứng dụng và ngữ cảnh mà ứng dụng sẽ hoạt động. Thực tế sẽ thuận lợi hơn rất nhiều nếu chúng ta tận dụng được những khả năng mà hệ thống hỗ trợ. Hy vọng qua bài báo này, các bạn phần nào nắm được cách thức thêm thông tin cấu hình vào cho ứng dụng của mình thông qua tập tin cấu hình mà .NET Framework hỗ trợ.

     

    Tên trường

     

     

    Mô tả

     

     

    NameValueSectionHandler

     

     

    Đọc thông tin cấu hình ở dạng một cặp Name-Value được trả về thông qua lớp đối tượng System.Collections.Specialized.NameValueCollection

     

     

    DictionarySectionHandler

     

     

    Đọc thông tin cấu hình ở dạng một cặp Key-Value được trả về thông qua lớp đối tượng System.Collections.Hashtable

     

     

    SingleTagSectionHandler

     

     

    Đọc thông tin cấu hình ở dạng một cặp Key-Value và trả về thông qua lớp đối tượng System.Collections.Hashtable

     

     

    IgnoreSectionHandler

     

     

    cung cấp một section handler định nghĩa cho configuration section được truy xuất và xử lý bởi hệ thống khác hơn là dùng System.Configuration. Để truy cập thông tin trong phần này, chúng ta phải đọc và duyệt qua toàn bộ thẻ XML trong tập tin cấu hình

     

     

    User-defined Section handlers

     

     

    do người dùng định nghĩa bằng cách cài đặt giao diện System.Configuration.IConfigurationSectionHandler

     

    Ngô Đình Nghĩa
    Global CyberSoft Vietnam

    nghiangodinh@yahoo.com

    ID: A0603_119