
Quicklibは、Delphi/Firemonkey(Windows、Linux、Android、OSX&IOS)およびFPC(Windows&Linux)ライブラリで、アプリケーション開発とクロスプラットフォームのサポートを簡素化し、生産性を向上させるために作成された興味深く、迅速な機能を実装しています。 Delphi XE8 -Delphi 12 Athensがサポートしました。
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クラウドストレージでBlob反復を簡素化します。
// 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オブジェクトを操作するためのUTIL。
// 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);2つのコード行で電子メールを送信します。
// 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:スレッドセーフキューリスト。自動序と重要なセクション。
tanonymousthread: Unchained ExecuteおよびOnterminateメソッドを定義する匿名スレッドを作成します。コードが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:障害および再試行制御ポリシーを備えたAutoFreeシングルタスクスレッドを起動します。パラマは渡されてコードに作成できます。
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テキストからのオブジェクトをシリアル化します。パブリックまたは公開が処理されるかどうかを定義できます(Delphi、FPC RTTIのみが公開されたプロパティのみをサポートしています)
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);JSONシリアル化およびマッピング関数が含まれているDTOクラスとして使用されます。
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: name-valueペア。値は、オブジェクト、配列、またはスカラーです。
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 ;Linqを任意のdujectList、Tlist、Tarray、およびTxArrayにクエリし、SQLの構文、更新、注文などの複合施設でSELECTを実行します。ここで、句はネームスペースを使用してネストされたプロパティを決定します。 LINQは、プロパティアレイに要素を検索できます。これで、通常の式を配列に追加、削除、検索するためのタレイヘルパーが含まれています。
// 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);removevalue:キャッシュからオブジェクトを削除します。
キャッシュエンジンプロバイダー:
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);コントロールマネージャーの反転により、インターフェンスオブジェクトのインターフェースを自動分解するか、コンストラクタークラスでそれらを自動インジェクトして、依存関係を回避できます。
依存関係の注入を管理するコンテナを作成します。
iocContainer := TIocContainer.Create;登録タイプ:
それらを挿入する前に、タイプを登録する必要があります。タイプは、一時的なシングルトンとして登録できます。 Singleton :ライフサイクルは、グローバル変数と同様に、すべての注入に対して1つのインスタンスになります。一時的:ライフサイクルは、各注入ごとに1つのインスタンスになります。インターフェイスタイプを一時的にコンテナに登録します。
iocContainer.RegisterType<IMultService,TMultService>.AsTransient;インターフェイスタイプをシングルトンとして登録し、建設を委任します。
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を登録する(シングルトンのみ):
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 );インターフェイスインスタンスは自動的に解放されますが、インスタンスの依存関係はSingletonとして定義された場合にのみ解放され、一時的なインスタンスはコードによって破壊されます。
セクションをクラスとして定義し、単一のファイル設定として保存します。 dotnetオプションと同様の動作。オプションファイルは、JSONまたはYAML形式を使用できます。
Toptionsから継承されたオプションクラスを定義すると、公開されているすべてのプロパティがロード/保存されます。 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は、TOPTIONSへの依存関係の注射可能なインターフェイスです。 ioccontainer.registeroptionsに登録して、コンストラクターメソッドに注射可能にすることができます。
UIOptions := Options.GetSectionInterface<TUIOptions>. Value ;
UIOptions.WindowColor := clBlue;オプションの読み込み/保存:
ファイル設定からオプションを読み込みます:
options.Load;ファイル設定にオプションを保存します:
options.Save;リロードング化されたパラメーターを使用してコンテナ作成を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;Interfacedリストとオブジェクトリストを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);デバッグユーティルパフォーマンスをチェックしてEnter Method Method CheckPoint.Ext.Define define a debug aコンパイラディレクティブは、アプリがデバッグモードでコンパイルされている場合にのみアクティブになるようにします。コンソールアプリでは、デフォルトでコンソールを使用します。ロガーを渡して出力します。
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,50sENTERとEXIT機能のときに通知を取得し、次の時間を取得します。
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 コマンドラインパラメーターを使用すると、コマンドライン拡張機能を使用して簡単です。公開されたプロパティとして、可能な引数を使用して、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 ;
PARAMを使用:
params := TMyParameter.Create;-helpでexeを呼び出すと、ドキュメントを取得します。スイッチや値を確認する必要がある場合は、次のようにできます。
if params.Port = 0 then ...
if params.Silent then ...QuickParametersは、特別なパラメーター条件を定義するためにカスタム属性を使用します。
CommandDescription:ヘルプドキュメントでアプリケーションを説明するテキストを定義します。
ParamCommand(number):単一パラメーターの静的位置をコマンドラインに定義します。
paramname(名前、エイリアス):パラメーターの異なる名前を定義します。クラスプロパティ(ファイル名やconfig.fileなど)に許可されていない特殊文字を使用できます。オプションのエイリアス引数は、代替(通常は短い名前)パラメーター名を定義します。
Paramhelp(Helptext、ValueName):使用法セクションでコマンドラインヘルプテキストと値名を定義します。
ParamswitchChar(sign):スイッチまたはパラメーターを示す文字列またはcharを定義します。定義されていない場合、デフォルトでダブルダッシュ( - )が使用されます。
ParamValueSeparator(sign):文字列またはcharを定義して、パラメーター名を値(filename = config.json)から個別にします。定義されていない場合、equal sign(=)はデフォルトで使用されます。
paramvalueisnextparam:値セパレーターなしの値を持つパラメーターを定義します(filename c: config.ini)
ParamRequired:必要に応じてパラメーターを定義します。 Paramが見つからない場合、例外が提起されます。
QuickParameterは、値タイプを自動的にチェックします。パラメーター値を整数として定義し、アルファニュメアーに合格すると、例外が提起されます。
カスタマイズのヘルプ: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
一般的に使用される検証。
流fluentスタイルの条件前後の検証。 condition.requires操作を行う前に、条件の変数を評価します。条件。エンゼチュアでは、操作を行った後の条件の変数結果を評価します。
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 evaluatesDelphiを学びたいですか、それともスキルを向上させたいですか? LearnDelphi.org