El aspecto 4Delphi consiste en una biblioteca que permite el uso del concepto de programación orientada a los aspectos (AOP) en Delphi.
AOP es un paradigma de programación que tiene como objetivo aumentar la modularidad al permitir la separación de preocupaciones transversales. Lo hace agregando un comportamiento adicional al código existente sin modificar el código en sí. En cambio, podemos declarar este nuevo código y estos nuevos comportamientos por separado.
Suppe4Delphi nos ayuda a implementar estas preocupaciones transversales.
Para obtener una copia local en funcionamiento, siga estos simples pasos.
Para usar esta biblioteca, se requiere una versión actualizada de Delphi IDE (XE o superior).
Clonar el repositorio
git clone https://github.com/ezequieljuliano/Aspect4Delphi.git
Agregue la "ruta de búsqueda" de su IDE o su proyecto los siguientes directorios:
Aspect4Delphisrc
Para proporcionar el paradigma de orientación de aspecto en su proyecto con Suppe4Delphi, necesita:
Para ilustrar el uso, veamos una solución para administrar registros de una aplicación.
Implementar un atributo PointCut (preferiblemente hereda de SuppectAttribute):
interface
uses
Aspect.Core;
type
LoggingAttribute = class(AspectAttribute)
private
{ private declarations }
protected
{ protected declarations }
public
{ public declarations }
end;
implementation
end.
Implemente la clase que representa su aspecto y contiene los métodos de consejos (debe implementar la interfaz IASSPECT):
interface
uses
System.SysUtils,
System.Rtti,
Aspect,
Aspect.Core,
Logging.Attribute,
App.Context;
type
ELoggingAspectException = class(Exception)
private
{ private declarations }
protected
{ protected declarations }
public
{ public declarations }
end;
TLoggingAspect = class(TAspectObject, IAspect)
private
{ private declarations }
protected
procedure OnBefore(
instance: TObject;
method: TRttiMethod;
const args: TArray<TValue>;
out invoke: Boolean;
out result: TValue
); override;
procedure OnAfter(
instance: TObject;
method: TRttiMethod;
const args: TArray<TValue>;
var result: TValue
); override;
procedure OnException(
instance: TObject;
method: TRttiMethod;
const args: TArray<TValue>;
out raiseException: Boolean;
theException: Exception;
out result: TValue
); override;
public
{ public declarations }
end;
implementation
{ TLoggingAspect }
procedure TLoggingAspect.OnAfter(instance: TObject; method: TRttiMethod;
const args: TArray<TValue>; var result: TValue);
var
attribute: TCustomAttribute;
begin
inherited;
for attribute in method.GetAttributes do
if attribute is LoggingAttribute then
begin
LoggingFile.Add('After the execution of ' +
instance.QualifiedClassName + ' - ' +
method.Name
);
Break;
end;
end;
procedure TLoggingAspect.OnBefore(instance: TObject; method: TRttiMethod;
const args: TArray<TValue>; out invoke: Boolean; out result: TValue);
var
attribute: TCustomAttribute;
begin
inherited;
for attribute in method.GetAttributes do
if attribute is LoggingAttribute then
begin
LoggingFile.Add('Before the execution of ' +
instance.QualifiedClassName + ' - ' +
method.Name
);
Break;
end;
end;
procedure TLoggingAspect.OnException(instance: TObject; method: TRttiMethod;
const args: TArray<TValue>; out raiseException: Boolean;
theException: Exception; out result: TValue);
var
attribute: TCustomAttribute;
begin
inherited;
for attribute in method.GetAttributes do
if attribute is LoggingAttribute then
begin
LoggingFile.Add('Exception in executing ' +
instance.QualifiedClassName + ' - ' +
method.Name + ' - ' +
theException.Message
);
Break;
end;
end;
end.
Registre su atributo de Pointcut y su clase de aspecto en contexto (preferiblemente mantenga este contexto en la instancia de Singleton):
interface
uses
Logging.Aspect;
Aspect.Context;
function AspectContext: IAspectContext;
implementation
var
AspectContextInstance: IAspectContext = nil;
function AspectContext: IAspectContext;
begin
if (AspectContextInstance = nil) then
begin
AspectContextInstance := TAspectContext.Create;
AspectContextInstance.RegisterAspect(TLoggingAspect.Create);
end;
Result := AspectContextInstance;
end;
end.
En su clase de regla comercial, use el atributo para definir sus puntos de unión. Puede usar el constructor y el destructor para agregar su clase al tejedor.
interface
uses
System.SysUtils,
Logging.Attribute,
App.Context;
type
EWhatsAppMessageException = class(Exception)
private
{ private declarations }
protected
{ protected declarations }
public
{ public declarations }
end;
TWhatsAppMessage = class
private
{ private declarations }
protected
{ protected declarations }
public
constructor Create;
destructor Destroy; override;
[Logging]
procedure Send; virtual;
end;
implementation
{ TWhatsAppMessage }
constructor TWhatsAppMessage.Create;
begin
inherited Create;
AspectContext.Weaver.Proxify(Self);
end;
destructor TWhatsAppMessage.Destroy;
begin
AspectContext.Weaver.Unproxify(Self);
inherited Destroy;
end;
procedure TWhatsAppMessage.Send;
begin
//Execution of send.
end;
Consulte los problemas abiertos para una lista de características propuestas (y problemas conocidos).
Las contribuciones son las que hacen que la comunidad de código abierto sea un lugar tan increíble para aprender, inspirar y crear. Cualquier contribución que haga es muy apreciada .
git checkout -b feature/AmazingFeature )git commit -m 'Add some AmazingFeature' )git push origin feature/AmazingFeature ) Distribuido bajo la licencia Apache. Vea LICENSE para más información.
Para contactarnos, use las opciones:
https://github.com/ezequieljuliano/aspect4delphi