欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
INI persistence the RTTI way

INI persistence the RTTI way

This post is based around the IniPersit.pas code that I just released.

I commonly create configuration classes to create a common and easy way to access information stored in INI, Registry, or XML. In these examples I will show how I used the new RTTI and Attributes in Delphi 2010 to provide a new way of creating a configuration class that access information stored in an INI file.

Lets first start off showing how to use the New Unit, then we can pull back the covers and show how it works.

01.unit ConfigSettings;
02.interface
03.uses
04.IniPersist;
05. 
06.type
07.TConfigSettings = class (TObject)
08.private
09.FConnectString: String;
10.FLogLevel: Integer;
11.FLogDirectory: String;
12.FSettingsFile: String;
13.public
14.constructor create;
15.// Use the IniValue attribute on any property or field
16.// you want to show up in the INI File.
17.[IniValue('Database','ConnectString','')]
18.property ConnectString : String read FConnectString write FConnectString;
19.[IniValue('Logging','Level','0')]
20.property LogLevel : Integer read FLogLevel write FLogLevel;
21.[IniValue('Logging','Directory','')]
22.property LogDirectory : String read FLogDirectory write FLogDirectory;
23. 
24.property SettingsFile : String read FSettingsFile write FSettingsFile;
25.procedure Save;
26.procedure Load;
27. 
28.end;
29. 
30.implementation
31.uses SysUtils;
32. 
33.{ TApplicationSettings }
34. 
35.constructor TConfigSettings.create;
36.begin
37.FSettingsFile := ExtractFilePath(ParamStr(0)) +  'settings.ini';
38.end;
39. 
40.procedure TConfigSettings.Load;
41.begin
42.// This loads the INI File Values into the properties.
43.TIniPersist.Load(FSettingsFile,Self);
44.end;
45. 
46.procedure TConfigSettings.Save;
47.begin
48.// This saves the properties to the INI
49.TIniPersist.Save(FSettingsFile,Self);
50.end;
51. 
52.end.

01.program Project13;
02. 
03.{$APPTYPE CONSOLE}
04. 
05.uses
06.SysUtils,
07.IniPersist,
08.ConfigSettings;
09. 
10.var
11.Settings : TConfigSettings;
12. 
13.begin
14.Settings := TConfigSettings.Create;
15.try
16.Settings.ConnectString := '\\127.0.0.1\DB:2032';
17.Settings.LogLevel := 3;
18.Settings.LogDirectory := 'C:\Log';
19.Settings.Save;
20.finally
21.Settings.Free;
22.end;
23. 
24.Settings := TConfigSettings.Create;
25.try
26.Settings.Load;
27.WriteLn(Settings.ConnectString);
28.Writeln(Settings.LogLevel);
29.Writeln(Settings.LogDirectory);
30.finally
31.Settings.Free;
32.end;
33.Readln;
34.end.

Output:
\\127.0.0.1\DB:2032
3
C:\Log

Resulting INI File:
[Database]
ConnectString=\\127.0.0.1\DB:2032
[Logging]
Level=3
Directory=C:\Log


As you can see by the above code there really is not much too it, if you want a field or a property to be stored in the INI File, you just need to add the IniValue Attribute.
1.TExampleClass = class (TObject)
2.private
3.FConnectString: String;
4.public
5.[IniValue('Database','ConnectString')]
6.property ConnectString : String read FConnectString write FConnectString;
7.end;

The constructor of the INIValue allows you to specify the Section, Name you the field or Property stored in. It also allows you to specify a default value if the name & section did not exist in the INI File.
01.IniValueAttribute = class(TCustomAttribute)
02.private
03.FName: string;
04.FDefaultValue: string;
05.FSection: string;
06.published
07.constructor Create(const aSection : String;const aName : string;const aDefaultValue : String = '');
08.property Section : string read FSection write FSection;
09.property Name : string read FName write FName;
10.property DefaultValue : string read FDefaultValue write FDefaultValue;
11.end;
12. 
13....
14. 
15.constructor IniValueAttribute.Create(const aSection, aName, aDefaultValue: String);
16.begin
17.FSection := aSection;
18.FName := aName;
19.FDefaultValue := aDefaultValue;
20.end;


So the magic is really contained in TIniPersist

01.TIniPersist = class (TObject)
02.private
03.class procedure SetValue(aData : String;var aValue : TValue);
04.class function GetValue(var aValue : TValue) : String;
05.class function GetIniAttribute(Obj : TRttiObject) : IniValueAttribute;
06.public
07.class procedure Load(FileName : String;obj : TObject);
08.class procedure Save(FileName : String;obj : TObject);
09.end;

The load and save methods are nearly identical, so lets take a look at load.
01.class procedure TIniPersist.Load(FileName: String; obj: TObject);
02.var
03.ctx : TRttiContext;
04.objType : TRttiType;
05.Field : TRttiField;
06.Prop  : TRttiProperty;
07.Value : TValue;
08.IniValue : IniValueAttribute;
09.Ini : TIniFile;
10.Data : String;
11.begin
12.ctx := TRttiContext.Create;
13.try
14.Ini := TIniFile.Create(FileName);
15.try
16.objType := ctx.GetType(Obj.ClassInfo);
17.for Prop in objType.GetProperties do
18.begin
19.IniValue := GetIniAttribute(Prop);
20.if Assigned(IniValue) then
21.begin
22.Data := Ini.ReadString(IniValue.Section,IniValue.Name,IniValue.DefaultValue);
23.Value := Prop.GetValue(Obj);
24.SetValue(Data,Value);
25.Prop.SetValue(Obj,Value);
26.end;
27.end;
28.for Field in objType.GetFields do
29.begin
30.IniValue := GetIniAttribute(Field);
31.if Assigned(IniValue) then
32.begin
33.Data := Ini.ReadString(IniValue.Section,IniValue.Name,IniValue.DefaultValue);
34.Value := Field.GetValue(Obj);
35.SetValue(Data,Value);
36.Field.SetValue(Obj,Value);
37.end;
38.end;
39.finally
40.Ini.Free;
41.end;
42.finally
43.ctx.Free;
44.end;
45.end;

So you can see we basically loop through all the properties and field check for an Attribute, if it exists we get the current value which sets the TypeInfo in the TValue object. Then we assign the string returned from the INI file into the TValue and call SetValue()

Lets look at the two methods called.
1.class procedure SetValue(aData : String;var aValue : TValue);
2.class function GetIniAttribute(Obj : TRttiObject) : IniValueAttribute;

Lets look first at SetValue(). You will see that it depends on the TypeInfo being present in the TValue being passed in. We check the TValue and perform the conversions required to convert the String to the Correct Type before storing it
into the TValue.
01.class procedure TIniPersist.SetValue(aData: String;var aValue: TValue);
02.var
03.I : Integer;
04.begin
05.case aValue.Kind of
06.tkWChar,
07.tkLString,
08.tkWString,
09.tkString,
10.tkChar,
11.tkUString : aValue := aData;
12.tkInteger,
13.tkInt64  : aValue := StrToInt(aData);
14.tkFloat  : aValue := StrToFloat(aData);
15.tkEnumeration:  aValue := TValue.FromOrdinal(aValue.TypeInfo,GetEnumValue(aValue.TypeInfo,aData));
16.tkSet: begin
17.i :=  StringToSet(aValue.TypeInfo,aData);
18.TValue.Make(@i, aValue.TypeInfo, aValue);
19.end;
20.else raise EIniPersist.Create('Type not Supported');
21.end;
22.end;

Now lets take a look at GetIniAttribute() the goal of this method is to check to see if a given TRttimember (Field or Property) has the IniValue attribute, and if it does return it, otherwise return NIL.
01.class function TIniPersist.GetIniAttribute(Obj: TRttiObject): IniValueAttribute;
02.var
03.Attr: TCustomAttribute;
04.begin
05.for Attr in Obj.GetAttributes do
06.begin
07.if Attr is IniValueAttribute then
08.begin
09.exit(IniValueAttribute(Attr));  // Exit with a parameter new in Delphi 2010
10.end;
11.end;
12.result := nil;
13.end;

So all in all, its really not much code, and it make usage simple. Now granted TIniValue is not all that complex, but this situation could be applied to a variety of other applications.

RTTI Article List
本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
jquery datatable例子
.Net Core 使用 NPOI 導入Excel
支付寶接口(剛完成,應該是目前最好的了)-ASP.NET實(shí)例-www.knowsky.co...
cglib源碼學(xué)習交流
泛型與反射
PHP session使用 memcached的注意幾個(gè)細節
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久