用RTTI處理常式配置資訊

來源:互聯網
上載者:User

一般來說,程式多少都會有一些自己的配置資訊要儲存,不論是通常用的儲存到INI還是註冊表,或者是XML甚至YAML,總歸是要寫不少代碼處理的。

問題的麻煩在於,程式中實現操作配置資訊通常並不需要關注它是儲存在什麼地方,以什麼格式儲存,但是傳統的方法不論是調用TIniFile還是TRegistry或者是DOM,都是需要開發人員花一些時間精力浪費在這上面。

我前一陣寫個小程式,不高興弄配置這些麻煩事,於是利用前些年寫的一個架構代碼,實現了一套通用的配置序列化機制,這樣配置資訊管理起來就方便多了。

代碼詳見MDConfig單元。

基本組成是這樣:

TMCustomConfigSection
類實現了IMSerializable介面(定義在架構的MDComm中),意味著它可以被遞迴序列化——不過在已實現的INI檔案和註冊表檔案序列化
中,這種遞迴僅限於一層:即一個設定檔可以包括多個配置段,但是配置段下不能再有配置段。當然,架構中實現的通用序列化(二進位和XML)不受此限。

TMCustomConfig類則是可序列化的設定檔,派生自TPersistent。這個類裡除了可以包含配置資訊以外,還可以包括配置段。

TMCustomConfigSerializer類則是配置序列化基類,實現配置序列化的公用部分——即與具體序列化方式無關的部分。

TMIniSerializer類是INI檔案的序列化類別,通過它可以把設定檔序列化到INI檔案中去。

TMRegSerializer類是註冊表序列化類別。

配置的基本使用方法是這樣的:

分別從TMCustomConfigSection和TMCustomConfig派生自己的配置段類和配置類,在其中定義設定項目供程式使用。範例程式碼如:

    TMTestConfigSection = class(TMCustomConfigSection)
Private
FStringItem : String;
FIntItem : Integer;
FFloatItem : Double;
FDateItem : TDateTime;
Published
Property StringItem : String Read FStringItem Write FStringItem;
Property IntItem : Integer Read FIntItem Write FIntItem;
Property FloatItem : Double Read FFloatItem Write FFloatItem;
Property DateItem : TDateTime Read FDateItem Write FDateItem;
End;

TMTestConfig = class(TMCustomConfig)
Private
FSectionItem : TMTestConfigSection;
FStringItem : String;
public
Constructor Create(aDefaultSerializer : IMSerializer = Nil);
destructor Destroy; Override;
Published
Property SectionItem : TMTestConfigSection Read FSectionItem Write FSectionItem;
Property StringItem : String Read FStringItem Write FStringItem;
End;

Constructor TMTestConfig.Create(aDefaultSerializer : IMSerializer = Nil);
begin
Inherited Create(aDefaultSerializer);
FSectionItem := TMTestConfigSection.Create();
end;

destructor TMTestConfig.Destroy;
begin
FSectionItem.Free;
Inherited
end;


列化方式則可以自由選擇目前已經實現的四種:INI檔案,註冊表,二進位檔案,XML。序列化操作也可以選擇預設序列化或是指定序列化。預設序列化就是在
Config物件建構時傳入預設的序列化方式,指定序列化就是在調用Config對象的Load/Save方法時指定序列方式。當然,即使設定了預設序列
化方式,也是可以在調用Load/Save方法時重新指定的。

預設序列化:

  conf := TMTestConfig.Create(TMIniSerializer.Create('e:/temp/test.ini'));
conf.StringItem := 'This is default section item';
conf.SectionItem.StringItem := 'This is Section item';
conf.SectionItem.IntItem := 12345;
conf.SectionItem.FloatItem := 9.87654;
conf.SectionItem.DateItem := EncodeDate( 2009, 01, 02 );
conf.Save;

指定序列化:

  conf := TMTestConfig.Create;
conf.Load(TMIniSerializer.Create('e:/temp/test.ini'));
conf.Save(TMRegSerializer.Create(HKEY_CURRENT_USER, 'software/mental studio/devotee/test'));

注意,其中序列化器是通過引用計數維護的,會自動釋放,不需要顯示釋放。

mdf架構全部源碼下載。

只使用配置序列化部分的話,只需要MDComm和MDConfig兩個單元檔案(二進位和XML序列化需要MSerializ單元)。

在BCB中使用的特別注意事項:

要用一個Delphi單元來定義配置類,因為用到了Delphi的RTTI,雖然用C++來寫配置類也可以編譯,但是會發生執行階段錯誤。特別關鍵的是序列化器對象必須在Delphi單元中建立。形如:

Constructor TMainConfig.Create(aIniName : String);
begin
Inherited Create(TMIniSerializer.Create(aIniName, 'Default'));
end;

// 然後在BCB中這樣使用

TMainConfig * MainCfg = new TMainConfig(ChangeFileExt(Application->ExeName,".ini"));

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.