
Delphi Framework (Windows / Linux / Android / MacOSX / IOS) pour créer facilement des applications de bureau, mobiles et Web évolutives de haute performance. Delphi 10 à 12 Athènes soutenus.
S'il vous plaît "Star" ce projet dans GitHub! Cela ne coûte que des aides à référencer le code. 
Si vous trouvez ce projet utile, veuillez envisager de faire un don.
Abstractions:
Services:
MVC:
Extensions:
Extensions MVC:
Mises à jour:
QuickCore est un framework pour créer des applications de bureau / mobile / Web.
Le cadre entier est basé sur des tamis d'injection de dépendance. Un conteneur détient tous les services nécessaires à l'application, permettant des modifications faciles d'infrastructure avec un enfort mineur.
Les services sont automatiquement injectés dans le serveur et configurés à partir d'une seule unité "startup". Chaque projet de base a besoin d'une startup.pas avec une classe héritée de TStartupbase (voir des exemples sur le dossier des échantillons).
Il s'agit d'une collection de services où nous pouvons enregistrer des services prédéfinis ou personnalisés et contrôler son cycle de vie (Singleton, transitoire, ..). ServiceCollection est le conteneur d'intégration inclus dans QuickCore et prend en charge l'injection de constructeur par défaut.
services
.AddLogging(TLoggerBuilder.GetBuilder(TLoggerOptionsFormat.ofYAML,False)
.AddConsole(procedure(aOptions : TConsoleLoggerOptions)
begin
aOptions.LogLevel := LOG_DEBUG;
aOptions.ShowEventColors := True;
aOptions.ShowTimeStamp := True;
aOptions.ShowEventType := False;
aOptions.Enabled := True;
end )
.AddFile(procedure(aOptions : TFileLoggerOptions)
begin
aOptions.FileName := ' .WebApiServer.log ' ;
aOptions.MaxFileSizeInMB := 200 ;
aOptions.Enabled := True;
end )
.Build
)
.AddDebugger
.AddOptions(TOptionsFileFormat.ofYAML,True)
// add entity database
.Extension<TEntityServiceExtension>
.AddDBContext<TShopContext>(TDBContextOptionsBuilder.GetBuilder.UseSQLite.ConnectionStringName( ' ShopContext ' ).Options)
// add Identity
.Extension<TAuthenticationServiceExtension>()
.AddIdentity<TUser,TRole>(procedure(aOptions : TIdentityOptions)
begin
aOptions.Password.RequiredLength := 6 ;
aOptions.User.RequireUniqueEmail := True;
end )
.AddEntityStore<TShopContext>();
// add Authentication
services.Extension<TAuthenticationServiceExtension>()
.AddAuthentication(procedure(aOptions : TAuthenticationOptions)
begin
end );
// add ApiKey Authentication
services.Extension<TApiKeyAuthenticationServiceExtension>
.AddApiKey()
.UseIdentityStore<TUser,TRole>( ' ApiKey ' );
// add Authorization
services.Extension<TAuthorizationServiceExtension>
.AddAuthorization(procedure(aOptions : TAuthorizationOptions)
begin
aOptions.AddPolicy( ' ApiKeyValidation ' ,TAuthorizationPolicyBuilder.GetBuilder
.RequireAuthenticatedUser.Build
// .RequireClaim(TClaimTypes.Role,'Admin').Build
);
end );QuickCore fonctionne avec l'interface ILogger. Nous pouvons utiliser l'extension de journalisation de l'engagement ou définir sa propre implémentation et l'injecter.
Pour utiliser la mise en œuvre de QuickLogger (Besoin de la bibliothèque QuickLogger. Voir les exigences d'installation). QuickLogger utilise un générateur d'Ilogger pour une configuration facile. Les options par défaut peuvent être transmises en tant que fonction de délégué d'options. Lorsque le fichier de configuration QuickLogger existe, aucune option par défaut ne sera appliquée davantage:
services
.AddLogging(TLoggerBuilder.GetBuilder(TLoggerOptionsFormat.ofYAML,False)
.AddConsole(procedure(aOptions : TConsoleLoggerOptions)
begin
aOptions.LogLevel := LOG_DEBUG;
aOptions.ShowEventColors := True;
aOptions.ShowTimeStamp := True;
aOptions.ShowEventType := False;
aOptions.Enabled := True;
end )
.AddFile(procedure(aOptions : TFileLoggerOptions)
begin
aOptions.FileName := ' .WebApiServer.log ' ;
aOptions.MaxFileSizeInMB := 200 ;
aOptions.Enabled := True;
end )
.Build
);... ou ajouter sa propre implémentation d'enregistrement
services.AddLogging(MyLogger);Le fichier de configuration de la journalisation QuickCore est enregistré en tant que fichier QuickLogger.yml O JSON. En utilisant la variable d'environnement Core_environment, nous pouvons définir quelle utilisation du fichier pour chaque implémentation. Si la variable d'environnement est définie, QuickCore essaiera de charger / enregistrer le fichier "QuickCore. [Core_environment] .yaml / json".
QuickCore fonctionne avec le modèle d'options. Chaque objet Toptions sera enregistré en tant que section dans le fichier de configuration et peut être injecté dans des constructeurs de services ou de contrôleurs. Le service d'options doit être ajouté à ServiceCollection avant de pouvoir ajouter des sections. Nous pouvons définir le nom de fichier de configuration et le format JSON ou YAML.
.AddOptions(TOptionsFileFormat.ofYAML,True)Chaque section de configuration doit être ajoutée et peut être configurée avec des valeurs par défaut.
services.Configure<TAppSettings>(procedure(aOptions : TAppSettings)
begin
aOptions.Smtp := ' mail.domain.com ' ;
aOptions.Email := ' [email protected] ' ;
end )
Et nous pouvons l'injecter plus tard aussi simple que ...
constructor TMyController.Create(aLogger : ILogger; aAppSettings : IOptions<TAppSettings>);
begin
fOptions := aAppSettings. Value ;
fSMTPServer.Host := fOptions.Smtp;
end ;Dans la configuration de démarrage, vous pouvez utiliser des options de lecture pour effectuer des actions facultatives:
if services.GetConfiguration<TAppSettings>.UseCache then
begin
// do some stuff or define service implementation
end
else
begin
// do some stuff or define alternative service implementation
end ;En utilisant la variable d'environnement Core_environment, nous pouvons définir quelle utilisation du fichier pour chaque implémentation. Si la variable d'environnement est définie, QuickCore essaiera de charger / enregistrer le fichier "QuickCore. [Core_environment] .yaml".
Si le nom est défini, le nom de classe sera utilisé comme nom de section dans le fichier config. Chaque option configurée sera enregistrée et charge dans le fichier de configuration, mais si nous le souhaitons, nous pouvons masquer certaines options pour être enregistrées. Utilisez des options.HideOptions: = true (pour les options internes non configurables à l'extérieur).
Debugger est un simple traceur-débugger (voir la documentation QuickLib). Pour connecter le débogueur avec un service de journalisation, il suffit d'ajouter un service de débogueur dans ServiceCollection (par défaut, utilise une sortie de console):
services.AddDebugger;Travailler avec les paramètres de ligne de commande sera facile à l'aide de l'extension de ligne de commande. Définissez une classe héritée de TParameters ou TServiceParameters (si vous travaillez avec QuickAppServices) avec vos arguments possibles:
uses
Quick.Parameters;
type
TArguments = class (TParameters)
private
fPort : Integer;
fSilent : Boolean;
published
[ParamCommand( 1 )]
[ParamHelp( ' Define listen port ' , ' port ' )]
property Port : Integer read fPort write fPort;
property Silent : Boolean read fSilent write fSilent;
end ;Et passer à l'extension de la ligne de commande:
services.AddCommandline<TArguments>;Lorsque vous appelez votre exe avec - help, vous obtenez une documentation. Si vous devez vérifier un commutateur ou une valeur, vous pouvez faire comme ceci:
if services.Commandline<TArguments>.Port = 0 then ...
if services.Commandline<TArguments>.Silent then ...Des interfaces et des implémentations peuvent être ajoutées à la service de service. AddSingleton et AddTransient permettent de définir le cycle en direct.
services.AddSingleton<IMyService,TMyService>;ou avec la création déléguée
services.AddTransient<IMyService,TMyService>(function : TMyService)
begin
Result := TMyService.Create(myparam);
Result.Host := ' localhost ' ;
end );ou ajouter une implémentation
services.AddSingleton<TMyService>;Les extensions sont des services injectables que nous pouvons ajouter à notre application / serveur. Les extensions sont injectées dans l'unité de démarrage de la collection des services. Les extensions de méthode de service de service fonctionnent similaires aux méthodes d'extension .NET, prolongeant la service de service.
Pour ajouter une extension, nous devons ajouter son unité à l'unité de démarrage utilise la clause (voir les extensions prédéfinies QuickCore ci-dessus).
uses
Quick.Core.Extensions.AutoMapper;
...
begin
services.Extension<TAutoMapperServiceExtension>
.AddAutoMapper;
end ;Avec QuickCore, nous pouvons créer des applications Web avec des contrôleurs et des actions.
Créez un serveur d'applications et définissez la liaison et la sécurité.
ApiServer := TMvcServer.Create( ' 127.0.0.1 ' , 8080 ,False);
ApiServer.UseStartup<TStartup>;
ApiServer.Start;
```delphi
To configure services and middlewares startup must configured
```delphi
class procedure TStartup.Configure (app : TMVCServer);
begin
app
.AddControllers
.AddController(THomeController)
.DefaultRoute(THomeController, ' Home/Index ' )
.UseWebRoot( ' .wwwroot ' )
.UseRouting
.UseMVC;
end ;AddController (ContropleClass): Ajoutez un contrôleur à un serveur d'applications Web.
AddControllers: Ajoutez tous les contrôleurs enregistrés lors de son unité d'initialisation avec RegisterController (ControperClass);
Utilisezwebroot (chemin): définissez le dossier statique des fichiers / données.
USECUSUMERRORPAGES: Activez l'utilisation des pages d'erreur personnalisées. Sur une erreur 403, le serveur recherchera des fichiers 403.html, 40x.html ou 4xx.html. Si la page dinamique spécifiée, les modèles de moustache simples seront remplacés par des informations d'erreur (StatusCode, StatusMSG, etc.).
USEMUSTACHEPAGES: moteur de modèle de moustache simple pour remplacer les vues simples.
Middlewares est comme des couches de fonctionnalités et se déroule dans un pipeline de demande. Chaque demande réussit pour chaque Middlwares (dans l'ordre de création) ou non, selon les requérits Middelware.
USESTATICFILES: pour permettre de servir un contenu statique.
USEHSTS: HTTP Strict Transport Security Middleware pour autoriser uniquement les connexions HTTPS.
UseHTTPSRedirection: permet de rediriger le middleware pour rediriger sur l'emplacement de l'en-tête trouvé.
Useroutage: permet de rouler middleware pour obtenir une route correspondante à partir de la demande.
USEMVC: Activer MVC Middleware pour gérer et rediriger chaque demande vers son action de contrôleur correspondant.
Usemiddleware: Pour ajouter une classe de middleware personnalisée pour demander un pipeline.
Use (requestdelegate): exécutez une méthode anonyme en tant que middleware.
Utilisation: essaie d'obtenir des informations d'authentification à partir d'une demande.
Utilisation: permettre / interdire les actualités aux ressources en fonction des politiques d'autorisation.
Chaque contrôleur hérite de ThTTPController et les méthodes publiées deviennent des actions. Avec les attributs personnalisés, nous pouvons définir le routage, l'autorisation, etc. de ces méthodes. Comme tous les contrôleurs sont injectés à partir de l'injection de dépendance, nous pouvons définir le constructeur avec des paramètres auto-injectables et le CIO essaiera de résoudre la création du constructeur.
constructor THomeController.Create(aLogger: ILogger);Le routage HTTP est basé sur des attributs personnalisés. Nous devons définir le routage pour chaque contrôleur et méthode / action.
[HttpGet( ' home/index ' )]
function THomeController.Index : IActionResult;
[HttpPost( ' home/GetAll ' )]
function THomeController.GetAll : IActionResult;Si le routage est défini sur la classe, il est global et n'a pas besoin d'être reproduit sur chaque méthode / action:
[Route( ' home/other ' )]
THomeController = class (THttpController)
published
[HttpPost( ' GetAll ' )] // global + local = home/other/GetAll
function THomeController.GetAll : IActionResult;Les paramètres sont définis avec des attributs et analysés automatiquement et injectés sous forme de paramètres de méthode.
[HttpGet( ' Add/{productname}/{price} ' )]
function Add ( const ProductName : string; Price : Integer): IActionResult;Les paramètres peuvent être tapés définis. INT: Numérique uniquement alpha: seulement des lettres. Float: seulement des nombres flottants.
[HttpGet( ' Add/{productname:alpha}/{price:float} ' )]
function Add ( const ProductName : string; Price : Extended): IActionResult;Un ? définir un paramètre comme facultatif
[HttpGet( ' Add/{productname:alpha}/{price:float?} ' )]
function Add ( const ProductName : string; Price : Extended): IActionResult;Pour obtenir un paramètre du corps de la demande (avec désérialisation automatique)
[HttpPost( ' Add/User ' )]
function Add ([FromBody] User : TUser): IActionResult;Les résultats de l'action sont les résultats d'un contrôleur. StatusCode (StatusCode, StatusTExt): Renvoie un code d'état et un texte d'état facultatif au client.
Result := StatusCode( 200 , ' ok ' );OK (StateStext): renvoie un code d'état 200 et Statustext facultatif.
Accepté (Statustext): renvoie un code d'état 202 et un texte d'état facultatif.
BadRequest (Statustext): renvoie un code d'état 400 et un texte d'état facultatif.
NotFound (Statustext): renvoie un code d'état 404 et un texte d'état facultatif.
Interdire (Statustext): renvoie un code d'état 403 et un texte d'état facultatif.
Non autorisé (Statustext): renvoie un code d'état 401 et un texte d'état facultatif.
Redirection (URL): Renvoie une redirection temporelle vers l'URL.
RedirectPerMament (URL): Renvoie une redirection permanente vers l'URL.
Contenu (texte): renvoie un texte de réponse.
JSON (objet, seulementPubliéProperties): Renvoie un objet ou une liste JSON sérialisée. Si seules les propriétés publiées activées, seules les propriétés publiées par objet seront sérialisées.
Result := Json(User);View (ViewName): renvoie une vue.
Result := View ( ' home ' );L'extension automatique permet à la carte un type de classe à un autre type de classe. Pour utiliser Automapper, nous devons ajouter un service à ServiceCollection dans l'unité de statistique:
services.Extension<TAutoMapperServiceExtension>
.AddAutoMapper;Définissez ensuite les cartes de profil avec la relation de cartographie. Si les noms de propriétés sont identiques, nous ne devons pas avoir à fournir manuellement une cartographie:
constructor TMyProfile.Create;
begin
// maps properties with same name in both classes
CreateMap<TDBUser,TUser>();
end ;
initialization
TAutoMapper.RegisterProfile<TMyProfile>;Si certaines propriétés ont un nom ou un type différent, nous devons utiliser des mappages personnalisés:
constructor TMyProfile.Create;
begin
// maps properties with delegate function and rest maps formember
CreateMap<TDBProduct,TProduct>(procedure(src : TDBProduct; tgt : TProduct)
begin
tgt.Id := src.uid;
tgt.Age := src.Age;
end )
.ForMember( ' Money ' , ' Cash ' )
.ForMember( ' Name ' , ' FullName ' )
.IgnoreOtherMembers;
end ;
initialization
TAutoMapper.RegisterProfile<TMyProfile>;Formember (SourceProperty, TargetProperty): mappe un nom de propriété source à un nom de propriété cible. IGNOREALLNONEXIST: Ignorez toutes les propriétés non existantes sur la cible.
IgnoreotherMembers: seules les propriétés définies dans la cartographie personnalisée seront résolues.
ResolveUnPapP: essaie de résoudre automatiquement n'importe quelle carte sans défini de profilemap.
Le service Automapper peut être injecté dans un objet / contrôleur définissant l'abstraction dans les clauses d'utilisation.
uses
Quick.Core.Mapping.Abstractions;
...
TMyController.Create(aMapper : IMapper);..et l'utiliser:
product := fMapper.Map(dbproduct).AsType<TProduct>;Voulez-vous apprendre Delphi ou améliorer vos compétences? Learndelphi.org