
Quicklib是Delphi/FiremonKey(Windows,Linux,Android,OSX和iOS)和FPC(Windows&Linux)库,包含有趣且快速实现功能,创建了旨在简化应用程序开发和交叉平台支持并提高生产率。 Delphi XE8 -Delphi 12雅典支持。
请在Github“星”这个项目!它无需花费,但有助于参考代码。 
如果您觉得这个项目有用,请考虑捐款。
功能领域:
主要单位描述:
更新:
允许使用相同代码简化调试任务的控制台应用程序作为控制台模式或服务模式。
if not AppService.IsRunningAsService then
begin
...your code running as console
end
else
begin
AppService.ServiceName := ' MyService ' ;
AppService.DisplayName := ' MyServicesvc ' ;
// you can pass an anonymous method to events
AppService.OnStart := procedure
begin
...your start code
end ;
AppService.OnExecute := YourExecuteFunction;
AppService.OnStop := YourStopFunction;
AppService.CheckParams;
end ;用Azure和Amazon Cloud Storage简化了Blob Iteraction。
// connect to a Azure blobstorage
QuickAzure := TQuickAzure.Create(AzureAccountName,AzureAccountKey);
// download a blob file to a stream
done := QuickAzure.GetBlob( ' MyContainer ' , ' MyFile.jpg ' ,ResponseInfo,MyStream);
// check if exists a folder
found := ExistFolder( ' MyContainer ' , ' /Public/Documents/Personal ' );
// list blobs starting with a pattern (recursively or not)
for azBlob in ListBlobs( ' MyContainer ' , ' /Public/Documents ' ,Recursive,ResponseInfo) do
begin
if azBlob.Size > 1000 then Showmessage(azBlob. Name );
end ;CIDR和IP范围功能。
// convert ip string to integer
IPv4ToInt( ' 192.168.1.10 ' );
// get first and last ip of a subnet scope
GetIpRange( ' 192.168.100.0 ' , ' 255.255.255.0 ' ,LowIp,HighIP);开发人员每天经常需要的功能。
// coverts UTC time TDateTime to Local date time
UTCToLocalTime(MyUTCTime);
// generate a 10 char length random password with alfanumeric and signs.
RandomPassword( 10 ,[pfIncludeNumbers,pfIncludeSigns]);
// Capitalize every word of a phrase
CapitalizeAll( ' the grey fox ' ); // returns "The Grey Fox"
// Simple TCounter and TTimeCounter for loops
counter := TCounter;
counter.Init( 200 );
timecounter : TTimeCounter;
timecounter.Init( 10000 );
while true do
begin
Inc(n);
{ your procedural process here }
// every 200 steps writes to console
if counter.Check then writeln(Format( ' Processed %d entries ' ,[n]));
// every 10 seconds writes to console
if timecounter.Check then writeln( ' Im working... ' );
end ;计时仪和基准测试很简单。
// get elapsed time execution of a code part
Chrono := TChronometer.Create(False);
Chrono.Start;
...code you need benchmark
Chrono.Stop;
// shows elapsed time in LongTime format (2 hour(s) and 10 minute(s))
Showmessage(Chrono.TimeElapsed(True));
// shows elapsed time in ShortTime format (02:10:00)
Showmessage(Chrono.TimeElapsed(False));
// get benchmak info of a process
Chrono := TChronoBenchMark.Create;
Chrono.TotalProcess := 100000 ;
for i := 1 to 10000 do
begin
{ your process here }
Chrono.CurrentProcess := i;
// shows estimated time your process will take in x hour(s), x minute(s) x second(s) format
writeln(Chrono.EstimatedTime(True));
// shows speed: num items per second processed of your process
writeln(Format( ' Items processed %d/sec ' ,[Chrono.Speed]));
end ;
writeln(Chrono.ElapsedTime(False)); // shows total time elapsed in 00:00:00 format 写日志消息以用颜色等等,以备件台...
// define which level of output needed
Console.Verbose := LOG_DEBUG;
// writes line to console in red color
cout( ' Error x ' ,etError);
// writes formatted line in green color
coutFmt( ' Proccess %s finished ' ,[ProccesName],etSuccess);
// writes integer
cout( 12348 );
// Connect a QuickLog and write to disk and screen with one line of code (with independent verbose levels)
MyQuickLog := TQuickLog.Create;
MyQuickLog.Verbose := LOG_ALL;
Console.Verbose := LOG_ONLYERRORS;
Console.Log := MyQuickLog;登录具有详细级别以及每日或最大空间旋转的磁盘或内存。
// write a header on start with info as running path, appname, debugmode, user, etc...
Log.ShowHeader := True;
// sets log with rotation at 20MB
Log.SetLog( ' .mylog.log ' ,False, 20 );
// write an error message
Log.Add( ' Error x ' ,etError);
// write formatted error message
Log.Add( ' Error is %s ' ,[ErrorStr],etError);加载/另存为JSON或YAML文件或Windows注册表密钥。从TappConfigjson,TappConfigyAml或TappConfigregistry创建一个descend类,并将加载/保存添加的已发布属性。文件配置可以在检测文件更改上重新加载。
// create a class heritage
TMyConfig = class (TAppConfigJson)
private
fName : string;
fSurname : string;
fStatus : Integer;
published
property Name : string read fName write fName;
property SurName : string read fSurname write fSurname;
property Status : Integer read fStatus write fStatus;
end ;
// create your config to json file
// Add Quick.Config.Json to your uses
MyConfig := TMyConfig.Create( ' Config.json ' );
MyConfig.Provider.CreateIfNotExists := True;
MyConfig.Provider.ReloadIfFileModified := True;
MyConfig. Name := ' John ' ;
MyConfig.Surname := ' Smith ' ;
// load
MyConfig.Load;
// save
MyConfig.Save;
// create your config to Windows Registry
// Add Quick.Config.Registry to your uses
MyConfig := TMyConfig.Create;
// Define Registry as HKEY_CURRENT_USERSoftwareMyApp
MyConfig.HRoot := HKEY_CURRENT_USER;
MyConfig.MainKey := ' MyApp ' ;
MyConfig. Name := ' John ' ;
MyConfig.Surname := ' Smith ' ;
// load
MyConfig.Load;
// save
MyConfig.Save;
// Create a custom Config with no default provider
TMyConfig = class (TAppConfig)
...your properties
end ;
MyConfig := TMyConfig.Create(TAppConfigJsonProvider.Create( ' .config.json ' );
监视文件以进行更改并抛出事件。
FileMonitor.Filename := ' .myfile.txt ' ;
// check file changes every 2 seconds
FileMonitor.Interval := 2000 ;
// watch for deleted or modified file events
FileMonitor.Notifies := [mnFileModified, mnFileDeleted)];
FileMonitor.OnFileChange := MyFileChangeFunction;
FileMonitor.Enabled := True;用于使用JSON对象的UTIT。
// When unit declared in uses, a TObject Helper allows all your objects to be loaded or saved to/from json string
MyObject.FromJson := jsonstring;
MyString := MyObject.ToJson;
// You can clone simple objects with clone function
MyObject1.Clone(MyObject2);发送带有两个代码行的电子邮件。
// Send email
SMTP := TSMTP.Create( ' mail.domain.com ' , 25 ,False);
SMTP.SendMail( ' [email protected] ' , ' [email protected] ' , ' Email subject ' , ' My message body ' );
// You can define more advanced options
SMTP.SenderName := ' John ' ;
SMTP.From := ' [email protected] ' ;
SMTP.Recipient := ' [email protected],[email protected] ' ;
SMTP.Subject := ' Email subject ' ;
SMTP.AddBodyFromFile := ' .body.html ' ;
SMTP.CC := ' [email protected] ' ;
SMTP.BCC := ' [email protected] ' ;
SMTP.Attachments.Add( ' .notes.txt ' );
SMTP.SendMail;线程安全类。
tthreadedqueuecs:关键部分的tthreadedqueue版本。
tthreadObjectList:线程安全对象列表。
tthreadedqueuelist:线程安全队列列表。自动和关键部分。
tanonymisthread:创建定义未链接执行和端接方法的匿名线程。如果需要更新UI,请使用execute_sync和onterminate_sync方法。
// simple anonymousthread
TAnonymousThread.Execute(
procedure
var
i : Integer;
begin
for i := 0 to 10 do cout( ' Working %d ' ,[i],etTrace);
cout( ' executed thread ' ,etSuccess);
end )
.OnTerminate(
procedure
begin
cout( ' terminated thread ' ,etSuccess);
cout( ' PRESS <ENTER> TO EXIT ' ,etInfo);
end )
.Start;Truntask:启动具有故障和重试控制策略的自动单个任务线程。参数可以传递并创建到代码中。
TRunTask.Execute(
procedure(task : ITask)
var
stream : TStringStream;
response : IHttpRequestResponse;
begin
stream := TStringStream.Create;
try
response := TJsonHttpClient(task[ ' httpclient ' ].AsObject).Get(task[ ' url ' ]);
task.Result := response.StatusCode;
if response.StatusCode <> 200 then raise Exception.Create(response.StatusText);
finally
stream.Free;
end ;
end )
.SetParameter( ' httpclient ' ,(TJsonHttpClient.Create),True)
.SetParameter( ' url ' , ' https://mydomain.com/testfile ' )
.WaitAndRetry( 5 , 250 , 2 )
.OnRetry(
procedure(task : ITask; aException : Exception; var vStopRetries : Boolean)
begin
// if error 404 don't try to retry request
if task.Result = 404 then vStopRetries := True;
end )
.OnException(
procedure(task : ITask; aException : Exception)
begin
coutFmt( ' Exception downloading (Error: %s / StatusCode: %d)... ' ,[aException.Message,task.Result.AsInteger],etError);
end )
.OnTerminated(
procedure(task : ITask)
begin
if task.Done then coutFmt( ' Download "%s" finished ok ' ,[task[ ' url ' ].AsString],etSuccess)
else coutFmt( ' Download "%s" failed after %d retries ' ,[task[ ' url ' ].AsString,task.NumRetries],etError);
end )
.Run;TbackgroundStasks:在背景中启动任务,允许数量有故障和重试控制策略的工人数量。如果代码需要更新UI,请使用AddTask_sync和OnTerminate_sync方法。
backgroundtasks := TBackgroundTasks.Create( 10 );
for i := 1 to 100 do
begin
mytask := TMyTask.Create;
mytask.Id := i;
mytask. Name := ' Task ' + i.ToString;
backgroundtasks.AddTask([mytask],False,
procedure(task : ITask)
begin
cout( ' task %d started ' ,[TMyTask(task.Param[ 0 ].AsObject).Id],etDebug);
TMyTask(task.Param[ 0 ].AsObject).DoJob;
end
).WaitAndRetry([ 250 , 2000 , 10000 ])
).OnException(
procedure(task : ITask; aException : Exception)
begin
cout( ' task %d failed (%s) ' ,[TMyTask(task.Param[ 0 ].AsObject).Id,aException.Message],etError);
end
).OnTerminated(
procedure(task : ITask)
begin
cout( ' task %d finished ' ,[TMyTask(task.Param[ 0 ].AsObject).Id],etDebug);
TMyTask(task.Param[ 0 ].AsObject).Free;
end
).Run;
end ;
backgroundtasks.Start;TSCHEDULEDTASKS:定时器的替代方案。您可以通过开始时间,重复选项和到期日期以及失败和重试控制策略分配任务。如果需要更新UI,请使用AddTask_sync,OnTerminate_sync和Onexpired_sync。您可以分配匿名方法来执行,异常,终止和到期事件。
myjob := TMyJob.Create;
myjob. Name := Format( ' Run at %s and repeat every 1 second until %s ' ,[DateTimeToStr(ScheduledDate),DateTimeToStr(ExpirationDate)]);
scheduledtasks.AddTask( ' Task1 ' ,[myjob],True,
procedure(task : ITask)
begin
cout( ' task "%s" started ' ,[TMyTask(task.Param[ 0 ]). Name ],etDebug);
TMyJob(task.Param[ 0 ]).DoJob;
end
).OnException(
procedure(task : ITask; aException : Exception)
begin
cout( ' task "%s" failed (%s) ' ,[TMyJob(task.Param[ 0 ]). Name ,aException.Message],etError);
end
).OnTerminated(
procedure(task : ITask)
begin
cout( ' task "%s" finished ' ,[TMyJob(task.Param[ 0 ]). Name ],etDebug);
end
).OnExpired(
procedure(task : ITask)
begin
cout( ' task "%s" expired ' ,[TMyJob(task.Param[ 0 ]). Name ],etWarning);
end
).StartAt(ScheduledDate
).RepeatEvery( 1 ,TTimeMeasure.tmSeconds,ExpirationDate);
scheduledtasks.Start;管理失败和重试策略,定义最大重试,等待培训之间的等待时间和破裂的麦内主义。
管理Windows进程。
// kill explorer process
KillProcess( ' explorer.exe ' );
// determine if an application is running
if IsProcessRunning( ' explorer.exe ' ) then Showmessage( ' Explorer is running! ' );
// get username who is running an exe
writeln( ' Explorer.exe open by: ' + GetProcessUser( ' explorer.exe ' );
// gets handle of a window with a 20 seconds timeout
if FindWindowTimeout( ' MainWindow ' , 20 ) then writeln( ' Window detected ' );管理Windows服务。
// detect if a service is installed
if not ServiceIsPresent( ' localhost ' , ' MySvc ' ) then raise Exception.Create( ' Service not installed! ' );
// Start a service
ServiceStart( ' localhost ' , ' MySvc ' );
// Uninstall a service
ServiceUninstall( ' MySvc ' );字符串格式。
// Format bytes to MB, GB, TB...
FormatBytes( 50000 ) // shows 50KB
FormatBytes( 90000000 ) // shows 90MB 将对象从/到JSON文本序列化。您可以定义是否将处理公共或已发布
json := ' {"name":"Peter","age":30} ' ;
serializer := TJsonSerializer.Create(TSerializeLevel.slPublishedProperty);
try
serializer.JsonToObject(user,json);
finally
serializer.Free;
end ;从一个类到另一个类的地图字段。允许自定义映射匹配不同的字段和自定义映射过程,以手动铸造/转换字段。
// Map values from User1 to User2
TMapper<TUser2>.Map(User);
// Map custom mappings
AutoMapper := TAutoMapper<TUser,TUser2>.Create;
// option1: you can define auto map different named properties
AutoMapper.CustomMapping.AddMap( ' Cash ' , ' Money ' );
AutoMapper.CustomMapping.AddMap( ' Id ' , ' IdUser ' );
// option2: you can decide to modify each property manually or allow to auto someones
AutoMapper.OnDoMapping := procedure( const aSrcObj : TUser; const aTargetName : string; out Value : TFlexValue)
begin
if aTargetName = ' Money ' then Value := aSrcObj.Cash * 2
else if aTargetName = ' IdUser ' then Value := aSrcObj.Id;
end ;
// option3: you can modify some properties after automapping done
AutoMapper.OnAfterMapping := procedure( const aSrcObj : TUser; aTgtObj : TUser2)
begin
aTgtObj.Money := aSrcObj.Cash * 2 ;
aTgtObj.IdUser := aSrcObj.Id;
end ;
User2 := AutoMapper.Map(User);用作DTO类,其中包括JSON序列化和映射功能。
type
TUser = class (TJsonRecord)
private
fName : string;
fAge : Integer;
published
property Name : string read fName write fName;
property Age : Integer read fAge write fAge;
end ;
var
user, user2 : TUser;
begin
user := TUser.Create;
// show as json string
Writeln(user.ToJson);
// mapping to other class
user.Mapto(User2);
Writeln(user2.ToJson);
// load from file
user.LoadFromFile( ' .user.json ' );
// save to file
user2.SaveToFile( ' .user2.json ' );
end ;具有索引或搜索功能的改进列表。
var
users : TIndexedObjectList<TUser>;
begin
users := TIndexedObjectList<TUser>.Create(True);
// create index by property "Name"
users.Indexes.Add( ' Name ' , ' Name ' ,TClassField.cfProperty);
// create index by private field "Id"
users.Indexes.Add( ' Id ' , ' fId ' ,TClassField.cfField);
// get user by "Name" index
writeln(users.Get( ' Name ' , ' Peter ' ).SurName);
end ;FlexValue存储任何数据类型,并允许通过集成运算符和自动帧传递到其他类。
var
value : TFlexValue;
str : string;
num : Integer;
begin
value := ' hello ' ;
str := value ;
value := 123 ;
num := value ;
end ;改进的阵列。
txarray:带有Tlist之类的方法的数组。
var
users : TXArray<TUser>;
begin
users.Add(User);
if users.Count:= TIndexedObjectList<TUser>.Create(True);
// create index by property "Name"
users.Indexes.Add( ' Name ' , ' Name ' ,TClassField.cfProperty);
// create index by private field "Id"
users.Indexes.Add( ' Id ' , ' fId ' ,TClassField.cfField);
// get user by "Name" index
writeln(users.Get( ' Name ' , ' Peter ' ).SurName);
end ;TFLEXARRAY:具有TLIST之类的方法的数组,而不是可以将不同的值类型存储到同一数组中。
var
flexarray : TFlexArray;
begin
flexarray.Add( 10 );
flexarray.Add( ' Hello ' );
user := TUser.Create;
try
user. Name := ' Joe ' ;
flexarray.Add(user);
cout( ' Integer Item = %d ' ,[flexarray[ 0 ].AsInteger],etInfo);
cout( ' String Item = %s ' ,[flexarray[ 1 ].AsString],etInfo);
cout( ' Record Item = %s ' ,[TUser(flexarray[ 2 ]). Name ],etInfo);
finally
user.Free;
end ;
end ;TFLEXPAIRARRAY:具有TLIST之类的方法的数组,而不是可以将不同的值类型存储到同一数组中,然后按项目名称搜索。
var
flexarray : TFlexPairArray;
begin
flexarray.Add( ' onenumber ' , 10 );
flexarray.Add( ' other ' , ' Hello boy! ' );
user := TUser.Create;
try
user. Name := ' Joe ' ;
flexarray.Add( ' myuser ' ,user);
cout( ' Integer Item = %d ' ,[flexarray.GetValue( ' onenumber ' ).AsInteger],etInfo);
cout( ' String Item = %s ' ,[flexarray.GetValue( ' other ' ).AsString],etInfo);
cout( ' Record Item = %s ' ,[TUser(flexarray.GetValue( ' myuser ' )). Name ],etInfo);
finally
user.Free;
end ;
end ;YAML对象结构。
tyamlobject: yaml对象是yamlvalue对的数组。
// create Yaml object from yaml text
yamlobj.ParseYamlValue(aYaml)
// add a pair
yamlobj.AddPair( ' Name ' , ' Mike ' );
// display as yaml structure
Writeln(yamlobj.ToYaml);Tyamlarray:对象或标量的数组。
yamlarray.AddElement(TYamlPair.Create( ' Age ' , 30 ));
yamlobj.AddPair( ' myarray ' ,yamlarray);TyamlPair:名称值对。值可以是对象,数组或标量。
n := yamlobj.GetPair( ' Name ' ). Value as TYamlInteger;从/到yaml序列化/值序列化对象。
// Serialize
text := YamlSerializer.ObjectToYaml(obj);
// Deserialize
YamlSerializer.YamlToObject(obj,yamltext);使用表达式评估对象属性或单个值。
if TExpressionParser.Validate(user,( ' (Age > 30) AND (Dept.Name = "Financial") ' ) then
begin
// do something
end ;
if TExpressionParser.Validate(user,( ' (20 > 30) OR (5 > 3) ' ) then
begin
// do something
end ;对任何TobjectList,TLIST,TARRAY和TXARRAY进行LINQ查询,并通过复杂进行选择,例如SQL语法,更新和订购列表。条款使用名称空间确定嵌套属性的地方。 Linq可以在属性数组中搜索元素。现在包括和tarray助手以添加,删除和搜索正则表达式中的数组。
// Select multi conditional
for user in TLinq<TUser>.From(userslist).Where( ' (Name = ?) OR (SurName = ?) OR (SurName = ?) ' ,[ ' Peter ' , ' Smith ' , ' Huan ' ]).Select do
begin
// do something
end ;
// Select like and update field
TLinq<TUser>.From(userlist).Where( ' SurName Like ? ' ,[ ' %son ' ]).SelectFirst. Name := ' Robert ' ;
// Select top and Order by field
for user in TLinq<TUser>.From(userlist).Where( ' Age > ? ' ,[ 18 ]).SelectTop( 10 ).OrderBy( ' Name ' ) do
begin
// do something
end ;
// update fields by conditional
TLinq<TUser>.From(userlist).Where( ' Name = ? ' ,[ ' Peter ' ]).Update([ ' Name ' ],[ ' Joe ' ]);
// count results
numusers := TLinq<TUser>.From(userlist).Where( ' (Age > ?) AND (Age < ?) ' ,[ 30 , 40 ]).Count;tcustomhttpserver是一个简单的接口httpserver,它具有自己的httprequest和httpresponse实现,可允许轻松的httpserver引擎更改。您可以启用自定义错误页面返回自定义页面和动态错误页面。 THTTPSERVER是Indyhttpserver实现,但您可以定义自己的实现。
TMyHttpServer = class (THttpServer)
public
procedure ProcessRequest (aRequest: IHttpRequest; aResponse: IHttpResponse); override;
end ;
procedure TMyHttpServer.ProcessRequest (aRequest: IHttpRequest; aResponse: IHttpResponse);
begin
aResponse.ContentText := ' Hello world! ' ;
end ;带有到期时间的缓存对象或字符串,以避免每次都需要生成此信息(数据库查询,难以计算信息等)。 tmemorycache允许缓存对象和字符串。通用版本tmemorycache允许仅缓存定义的类型。
// create MemoryCache with 10 seconds purge interval
cache := TMemoryCache.Create( 10 );
// create MemoryCache for a type
cache := TMemoryCache<TMyObj>.Create; // set string to cache without expiration
cache.SetValue( ' mystring ' , ' hello world ' );
// set string to cache with expiration to 10 seconds
cache.SetValue( ' mystring ' , ' this cache will expire in 10 seconds ' ;
// set object to cache
cache.SetValue( ' Obj1 ' ,valueobj); // get string query result
cache.GetValue( ' Query12 ' );
// get integer
cache.TryGetValue<Integer>( ' number ' ,valueint);
// get object
cache.TryGetValue( ' Obj1 ' ,valueobj);删除Value:从缓存中删除对象。
缓存引擎提供商:
tcacheserializerjson:使用JSON序列化缓存数据。
tcachecompressorgzip:使用GZIP压缩缓存数据。
tcachecompressorlzo:使用LZO压缩缓存数据。
// create MemoryCache with 20 seconds purge interval and compression with LZO engine
cache := TMemoryCache.Create( 10 , nil ,TCacheCompressorLZO.Create);Control Manager的倒置允许自动接口o实例对象或在构造函数类中自动注射它们,以避免依赖性。
创建一个容器来管理依赖注入。
iocContainer := TIocContainer.Create;注册类型:
您需要注册类型,然后才能注入。可以将类型注册为单例,瞬态。 Singleton :生命周期将是所有注射的一个实例,类似于全局变量。瞬态:生命周期是每次注射的一个实例。将接口类型注册到瞬态:
iocContainer.RegisterType<IMultService,TMultService>.AsTransient;注册接口类型为Singleton,委派结构:
iocContainer.RegisterType<ISumService,TSumService>.AsSingleTon.DelegateTo(
function : TSumService
begin
Result := TSumService.Create;
end
);注册实例:
注册一个命名实例对象为瞬态,委派结构:
iocContainer.RegisterInstance<TDivideService>( ' one ' ).AsTransient.DelegateTo(
function : TDivideService
begin
Result := TDivideService.Create(True);
end
);注册选项:
注册IOPTIONS(仅Singleton):
iocContainer.RegisterOptions<TMyOptions>(MyOptions);解决类型:
AbtractFactory:创建一个试图用依赖项注入解决所有创建方法参数的类。
MyClass := iocContainer.AbstractFactory<TMyBaseClass>(TMyClass);解决接口依赖性:
multservice := iocContainer.Resolve<IMultService>;
result := multservice.Mult( 2 , 4 );解决实例:
解决一个命名的实例依赖性:
divideservice := iocContainer.Resolve<TDivideService>( ' other ' );
result := divideservice.Divide( 100 , 2 );接口实例将自动释放,但是实例依赖性只有定义为单例,瞬态实例将被代码破坏。
您将部分定义为类,并保存为单个文件设置。类似于Dotnet选项的工作。选项文件可以是JSON或YAML格式。
定义您从上衣继承的选项类,所有已发布的属性都将是加载/保存。使用Jsonserializer并重新加载更改:创建选项容器:
Options := TOptionsContainer.Create( ' .options.conf ' ,TJsonOptionsSerializer.Create,True);将部分添加到您的容器选项中:
Options.AddSection<TLoggingOptions>( ' Logging ' )配置选项:
您可以定义截面名称以保存到文件中并委派配置默认设置并验证值:
Options.AddSection<TLoggingOptions>( ' Logging ' ).ConfigureOptions(
procedure(aOptions : TLoggingOptions)
begin
aOptions.Path := ' C: ' ;
end
).ValidateOptions;验证选项:
验证选项允许验证是否在定义范围之间设置了选项设置。此验证需要先前分配给Toptions类中属性的自定义属性。
TLoggingOptions = class (TOptions)
private
fPath : string;
published
[Required, StringLength( 255 , ' Path too long ' )]
property Path : string read fPath write fPath;
[Range( 0.0 , 5.2 )]
property Level : Double read fLevel write fLevel;
end ;使用选项:检索选项部分:
LoggingOptions := Options.GetSection<TLoggingOptions>;
LoggginOptions.Path := ' C:Path ' ;使用IOPTIONS: IOPTIONS是一个可依赖性的界面。您可以在ioccontainer.registeroptions中注册,以使其注射到构造函数方法中。
UIOptions := Options.GetSectionInterface<TUIOptions>. Value ;
UIOptions.WindowColor := clBlue;加载/保存选项:
从文件设置加载选项:
options.Load;将选项保存到文件设置:
options.Save;如果您定义了使用ReloAdonChanged参数定义为True的容器创建,则每次更改文件设置时,都会重新加载配置。如果您需要控制何时重新加载,则可以收听事件:
Options.OnFileModified := procedure
begin
cout('Detected config file modification!',etWarning);
end;
定义连接池,线程或您要控制的任何对象,以避免资源消耗,例如数据库连接,HTTP客户端等...
创建HTTP客户池:
pool := TObjectPool<THTTPClient>.Create( 5 , 5000 ,procedure( var aInstance : THTTPClient)
begin
aInstance := THTTPClient.Create;
aInstante.UserAgent := ' MyAgent ' ;
end );从池中获取对象:
httpcli := pool.Get.Item;
statuscode := httpcli.Get( ' https://www.mydomain.com ' ).StatusCode;用LINQ支持继承定义连接的列表和对象列表。
myarray := [ ' Joe ' , ' Mat ' , ' Lee ' ];
// search for regex match
cout( ' Search for regex match ' ,ccYellow);
for name in myarray.Where( ' e$ ' ,True).Select do
begin
cout( ' User %s ends with "e" ' ,[ name ],etInfo);
end ;user := ListObj.Where( ' Profile.Name = ? ' ,[ ' Lee ' ]).SelectFirst;表达搜索项目数组:
users := ListObj.Where( ' Roles CONTAINS ? ' ,[ ' SuperAdmin ' ]).Select;谓词搜索:
user := ListObj.Where(function(aUser : TUser) : Boolean
begin
Result := aUser. Name .StartsWith( ' J ' );
end ).SelectFirst;
if user <> nil then cout( ' %s starts with J letter ' ,[user. Name ],etInfo);请参阅quick.linq部分以查看允许的更多功能。
使用字典或委托功能替换字符串模板。您可以指定引用的令牌字符。
更换通过词典:
dict := TDictionary<string,string>.Create;
dict.Add( ' User ' , ' John ' );
dict.Add( ' Age ' , ' 20 ' );
dict.Add( ' SurName ' , ' Peterson ' );
mytemplate := ' User {{User}} {{SurName}} are {{Age}} years old. ' ;
template := TStringTemplate.Create( ' {{ ' , ' }} ' ,dict);
Result := template.Replace(mytemplate);替换为委托功能:
mytemplate := ' User {{User}} {{SurName}} are {{Age}} years old. ' ;
template := TStringTemplate.Create( ' {{ ' , ' }} ' ,function( const aToken : string) : string
begin
if token = ' User ' then Result := ' John '
else if token = ' Surname ' then Result := ' Peterson '
else if token = ' Age ' then Result := ' 20 ' ;
end );
Result := template.Replace(mytemplate);调试utils检查性能并获得Enter and Exit方法检查点。通过调试指令定义,仅在调试模式以调试模式编译应用程序时才处于活动状态。在控制台上,应用程序默认使用控制台。您可以将记录仪传递以输出:
TDebugUtils.SetLogger(ilogger);跟踪代码的一部分:
function TCalculator.Subs (a, b: Int64): Int64;
begin
{ $IFDEF DEBUG }
TDebugger.Trace(Self,Format( ' Substract %d - %d ' ,[a,b]));
{ $ENDIF }
Result := a - b;
// simulate working for 200ms
Sleep( 200 );
end ;
// Returns:
// 29-06-2020 23:31:41.391 [TRACE] TCalculator -> Substract 30 - 12计算从点到退出函数的处理时间:
function TCalculator.Sum (a, b: Int64): Int64;
begin
{ $IFDEF DEBUG }
TDebugger.TimeIt(Self, ' Sum ' ,Format( ' Sum %d + %d ' ,[a,b]));
{ $ENDIF }
Result := a + b;
// simulate working for 1 seconds
Sleep( 1000 );
end ;
// Returns:
// 29-06-2020 22:58:45.808 [CHRONO] TCalculator.Sum -> Sum 100 + 50 = 1,00s计算从点到点和退出功能处理的时间:
function TCalculator.Divide (a, b: Int64): Double;
begin
{ $IFDEF DEBUG }
var crono := TDebugger.TimeIt(Self, ' Divide ' ,Format( ' Divide %d / %d ' ,[a,b]));
{ $ENDIF }
Result := a / b;
// simulate working for 500ms
Sleep( 500 );
{ $IFDEF DEBUG }
crono.BreakPoint( ' Only divide ' );
{ $ENDIF }
// simulate working for 1 second
Sleep( 1000 );
{ $IFDEF DEBUG }
crono.BreakPoint( ' Only Sleep ' );
{ $ENDIF }
end ;
// Returns:
// 29-06-2020 23:25:46.223 [CHRONO] TCalculator.Divide -> First point = 500,18ms
// 29-06-2020 23:25:47.224 [CHRONO] TCalculator.Divide -> Second point = 1,00s
// 29-06-2020 23:25:47.225 [CHRONO] TCalculator.Divide -> Divide 10 / 2 = 1,50s输入和退出功能时获取通知,并在此范围内进行:
function TCalculator.Mult (a, b: Int64): Int64;
begin
{ $IFDEF DEBUG }
TDebugger.Enter(Self, ' Mult ' ).TimeIt;
{ $ENDIF }
Result := a * b;
// simulate working for 2 seconds
Sleep( 2000 );
end ;
// Returns:
// 29-06-2020 22:58:45.808 [ENTER] >> TCalculator.Mult
// 29-06-2020 22:58:47.810 [EXIT] >> TCalculator.Mult in 2,00s 使用Commandline扩展名,使用命令行参数很容易。定义从tparameters或tserviceParameters继承的类(如果与QuickAppServices一起使用),您可能的参数为已发布的属性:
uses
Quick.Parameters;
type
TCommand = (Copy, Move, Remove);
TMyMode = (mdAdd, mdSelect, mdRemove);
[CommandDescription( ' Simple console application example with Quick.Parameters ' )]
TMyParameter = class (TParameters)
private
fCommand : TCommand;
fHost : string;
fPort : Integer;
fRetries : Integer;
fUseTCP : Boolean;
fConfigFile: string;
fSilent: Boolean;
fMyMode: TMyMode;
fLogErrorsConsole: Boolean;
fLogErrors: Boolean;
fShowReport: Boolean;
published
[ParamCommand( 1 )]
[ParamRequired]
[ParamHelp( ' Command action. ' , ' command-action ' )]
property Command : TCommand read fCommand write fCommand;
[ParamName( ' HostName ' ),ParamRequired]
[ParamHelp( ' Define host to connect. ' , ' host ' )]
property Host : string read fHost write fHost;
[ParamName( ' Port ' , ' p ' )]
[ParamValueIsNextParam]
[ParamHelp( ' Define Port to connect (default 80) ' , ' port ' )]
property Port : Integer read fPort write fPort;
[ParamHelp( ' Number of max retries. ' )]
property Retries : Integer read fRetries write fRetries;
[ParamHelp( ' Path to config. ' , ' path ' )]
[ParamName( ' Config-file ' )]
property ConfigFile : String read fConfigFile write fConfigFile;
[ParamHelp( ' Silent mode. ' )]
property Silent : Boolean read fSilent write fSilent;
[ParamHelp( ' Modes (mdAdd, mdSelect, mdRemove) ' )]
property Mode : TMyMode read fMyMode write fMyMode;
end ;
使用参数:
params := TMyParameter.Create;当您与EXE打电话时 - 螺旋 - 您会收到文档。如果您需要检查开关或价值,则可以这样做:
if params.Port = 0 then ...
if params.Silent then ...QuickParameters使用自定义属性来定义特殊参数条件:
命令描述:定义文本以在帮助文档中描述您的应用程序。
ParamCommand(编号):将静态位置定义为单个参数的命令行。
参数(名称,别名):定义参数的不同名称。允许使用类属性不允许的特殊字符(例如文件名或config.file)。可选的别名参数定义了替代(通常是简短名称)参数名称。
paramhelp(Helptext,valueName):在用法部分中定义命令行帮助文本和值名。
ParamSwitchchar(标志):定义字符串或字符以指示开关或参数。如果未定义,则默认情况下将使用双仪表板( - )。
ParamValueseparator(符号):将字符串或字符定义为将参数名称与值分开(文件名= config.json)。如果未定义,则默认情况下将使用等符号(=)。
paramvalueisnextparam:定义一个具有无值分离器的值的参数(文件名C: config.ini)
paramrequired:根据需要定义一个参数。如果找不到参数,将提出异常。
QuickParameter会自动检查值类型。如果将参数值定义为整数,并传递Alfanumeric,则将提高例外。
帮助自定义:您可以使用ColorizeHelp定义自己的颜色自定义。启用属性将使用自定义颜色,否则将使用b/w。
Parameters.ColorizeHelp.Enabled := True;
Parameters.ColorizeHelp.CommandName := ccCyan;
Parameters.ColorizeHelp.CommandUsage := ccBlue;当参数检测帮助参数时,将显示帮助文档。
parameters.showhelp:显示自动生成的帮助文档:
Parameters v.1.0
Usage: Parameters <command-action> <--HostName=<host>> [--Port <port>] [--Retries=<value>]
[--Config-file=<path>] [--UseTCP] [--Silent] [--Mode=<value>]
[--ShowReport] [--Help]
Simple console application example with Quick.Parameters
Arguments:
Command Command action.
--HostName Define host to connect.
--Port, -p Define Port to connect (default 80)
--Retries Number of max retries.
--Config-file Path to config.
--UseTCP Use TCP connection if present.
--Silent Silent mode.
--Mode Modes (mdAdd, mdSelect, mdRemove)
--Help, -h Show this documentation
常用验证。
流利风格的前和后条件验证。条件。要求在进行某些操作之前评估条件的变量。条件。进行一些操作后评估条件的变量结果。
Condition.Requires(num, " num " )
.IsInRange( 1 , 10 , ' value for num is out of range ' ); // throws custom error if not in range
.IsNotGreater( 50 ); // throws ArgumentException if not equal to 128
Condition.Requires(myobj, " myobj " )
.WithExceptionOnFailure(EMyException) // throws specific exception on failure
.IsNotNull() // throws ArgumentNullException if null
.Evaluate(myobj.id > 10 ); // myobj.id must be greater than 10
Condition.Requires(text, " text " )
.IsNotEmpty() // throws ArgumentNullException if empty
.StartsWith( " <html> " ) // throws ArgumentException if not starts with <html>
.EndsWith( " </html> " ) // throws ArgumentException if not ends with </html>
.IsNotLowerCase // thows ArgumentException if not lowercase
.Evaluate(text.Contains( " sometxt " ) or test.Contains( ' othertxt ' )); // throws ArgumentException if not evaluates您想学习Delphi还是提高技能? Learndelphi.org